developer tip

.net ORM 비교

copycodes 2020. 12. 1. 08:21
반응형

.net ORM 비교


Entity Framework에 대해 누군가와 이야기하고 있었는데 아직은 그것에 대해 잘 모르지만 배우고 싶습니다. 그러나 나는 그것을 배워야할지 말지 여전히 혼란 스럽습니다. 많은 사람들이 엔티티 프레임 워크를 사용하지 말아야한다고 말하는 것을 들었지만 그 이유는 전혀 듣지 못했습니다.

그래서 내 질문은 다른 제품과 비교 하여 Entity Framework를 사용하는 장단점은 무엇입니까 ? 처럼

  • NHibernate
  • DataObjects.Net
  • 기타..

사용 편의성, 테스트 가능성, 의미론 측면에서 ...

이것에 대해 몇 가지 중복 질문있다는 것을 알고 있습니다 . 그러나 그것들은 모두 다소 구식이며 (2008,2009) 솔직히 말해서 논쟁에도 무언가 부족합니다. Entity Framework 4.0을 사용할 수 있으며 아직 좋은 (완전한) 비교를 찾지 못했습니다.


대답

여기에있는 몇몇 좋은 사람들은 다른 프레임 워크에 대한 세부 사항을 설명함으로써 제 질문에 답했습니다. 나중에 참조 할 수 있도록 여기에 표시하는 것이 좋을 것이라고 생각했습니다.


J. Tihon이 EF 기능을 훌륭하게 설명했기 때문에 NHibernate가 EF를 중심으로 원을 그리던 영역을 나열하겠습니다.

  • 캐싱
    • EF는 즉시 사용할 수있는 것이 없습니다. 단지 거기에 지원되지 않는 샘플
    • NH는 DB 기반 무효화를 포함하여 완전한 캐싱 지원을 제공합니다. 또한 확장 가능하고 공급자 기반이므로 다양한 유형의 로컬 및 분산 캐시와 함께 작동합니다.
  • 일괄 처리
    • EF에는 없음
    • NH는 한 번에 (모든 DB에서) 엔터티 또는 컬렉션의 지연로드 그룹을 광범위하게 지원하고 동일한 방식 (Oracle 및 SQL Server)으로 변경 사항을 유지합니다. MultiQueries 및 Future Queries도있어 한 번의 왕복으로 여러 쿼리를 임의로 그룹화 할 수 있습니다.
  • 사용자 유형
    • EF는 확장 성이 전혀 없습니다. Enum 속성도 지원하지 않습니다.
    • NH에서는 유형 매핑이 하드 코딩되지 않습니다. 생성 할 수있는 모든 값 유형을 지원하도록 확장하고 기존 유형이 매핑되는 방식 등을 수정할 수 있습니다.
  • 수집 지원
    • EF는 단순한 엔터티 컬렉션 만 지원합니다. 다대다는 항상 복합 키를 사용합니다.
    • NH는 엔티티, 값 유형, 구성 요소 유형, 색인화 된 콜렉션 및 사전 (키와 값 모두 유형이 될 수 있음)의 콜렉션을 지원합니다. 자체 키가있는 다 대다 컬렉션 지원 (idbag)
  • 벌채 반출
    • EF는 즉시 로그 아웃 할 수 없습니다. 위에 나열된 동일한 지원되지 않는 샘플이 있습니다.
    • NH는 광범위한 로깅을 제공하므로 문제를 쉽게 디버깅 할 수 있습니다. 기본적으로 log4net을 사용하지만 원하는 로깅 프레임 워크를 사용할 수 있습니다.
  • 질의
    • EF에는 기본 쿼리 언어로 LINQ가 있습니다. LINQ는 관계형 데이터베이스에 매핑 할 때 임피던스가 높습니다. EF의 공급자는 엔터티를 매개 변수로 사용하는 것을 지원하지 않습니다. 항상 ID를 사용해야합니다. 제대로 문서화되지 않은 쿼리 언어도 있습니다.
    • NH에는 LINQ (하지만 EF만큼 완전하지는 않음), HQL, QueryOver 및 Criteria가 있습니다.
  • 이벤트 시스템 및 인터셉터
    • EF에는 거의 아무것도 없습니다
    • NH는 세션 라이프 사이클의 어느 시점에서든 동작을 확장하거나 대체 할 수있는 강력한 이벤트 시스템을 가지고 있습니다 : 객체로드, 변경 사항 지속, 플러싱 등.

확장 성이 주요 판매 포인트라고 생각합니다. NH의 모든 측면은 필요할 때마다 확장 할 수 있고 구성 옵션에 노출 될 수있는 인터페이스 및 기본 클래스를 사용하여 나머지 부분과 올바르게 분리됩니다.

EF는 기본적으로 작업을 닫는 일반적인 MS 패턴을 따르며 나중에 확장 가능한 항목을 볼 수 있습니다.


필자는 Entity Framework를 내 요구에 맞게 조정하는 데 엄청난 시간을 소비하므로 ORM에서 원하는 대부분의 요구 사항을 충족한다고 말할 수 있습니다. 그러나 다른 ORM이 더 쉽게 만들 수 있음을 보여준 것처럼 일부 측면은 너무 복잡합니다.

예를 들어 Entity Framework를 시작하는 것은 매우 쉽습니다. Visual Studio에서 디자이너를 실행하고 몇 분 안에 ORM을 작동시킬 수 있기 때문입니다. 그러나 디자이너가 만든 ObjectContext에 연결된 Entity-Classes로 끝납니다 (사용자 지정 T4 템플릿을 사용하여 피할 수 있음). 이것은 반드시 나쁜 것은 아니지만 실제 응용 프로그램에서 사용하고 싶지 않은 Microsoft "시작"접근 방식입니다.

하지만 Entity Framework에 대해 자세히 살펴보면 대부분의 함정을 피할 수있는 방법을 알 수 있습니다. Designer는 EDMX 파일을 생성합니다.이 파일은 XML 편집기에서 보면이 세 가지의 조합에 지나지 않습니다. ORM의 주요 측면, 물리적 저장소 (데이터베이스), 개념적 모델 (엔티티 클래스) 및 둘 사이의 매핑. Visual Studio의 .edmx 파일에 적용된 사용자 지정 빌드 작업은 이러한 세 부분을 세 개의 개별 파일로 분할하고 어셈블리에 포함 된 리소스로 추가합니다. ObjectContext를 만들 때이 세 파일에 대한 경로는 ConnectionString에서 사용됩니다 (항상 저에게 약간 혼란스러워 보입니다). 여기서 실제로 할 수있는 것은이 모든 것을 혼자서하는 것입니다. 이것은 스토리지 스키마를 작성하는 것을 의미합니다.

기본 Entity Framework 기본 클래스 "ObjectContext"는이 세 파일에서 생성 할 수 있지만 (MetadataWorkspace 및 EntityConnection 사용) 요점은 ObjectContext가 생성되는 방식을 완전히 제어 할 수 있다는 것입니다. 이렇게하면 Entity Framework에서 기대할 수없는 많은 기능에 대한 문이 열립니다. 예를 들어 특정 데이터베이스 유형과 일치하도록 동일한 어셈블리에 여러 SSDL 저장소 스키마를 포함 할 수 있습니다 (일반적으로 SQL Server 용 하나와 SQL Server CE 4.0 용 하나 추가). 그리고 특정 종류의 DbConnection에 적합한 스토리지 스키마를 선택하는 생성자 오버로드를 만듭니다.

이제 고유 한 ObjectContext 구현이 있으므로 다양한 인터페이스를 구현할 수 있습니다. 자신의 IRepository와 비슷하지만 ObjectContext 접근 방식을 좋아하기 때문에 다음과 같은 것을 만듭니다.

interface ICatalog
{
    IEntitySet<Article> { get; }
    void Save();
}

interface IEntitySet<T> : IQueryable<T>
{
    void Add(T);
    void Remove(T); 
}

class EntityFrameworkCatalog : ICatalog
{
    ...
}

But creating a Repository if you have an Entity Framework ObjectContext is really easy, plus you get an IQueryable. Based on this information you can avoid having strong class coupling between your services and the ORM and completly mock out the Entity Framework in tests. Also, when testing your Entity Framework implementation, you can use a SQL Server CE database during unit-tests to ensure that your mappings are fine (usually the different between the storage schema for CE and the full blown SQL Server is just a few data-types). So you can actually test all behaviors of your Entity Framework implemantion just fine.

This makes Entity Framework place nicely with modern software concepts, but it doesn't enforce such practices on you, which makes the "Getting Started" easier.

Now to the complex bits: The Entity Framework has a small set of supported CLR types, which basically only include the primitive ones, like ints, strings and byte-arrays. It also provides some level of complex-types, which follow the same rules. But what if you have a complex entity property such as a DOM representation of a document, which you would like to have serialized to XML in the database. As far as i know, NHibernate provides a feature called IUserType, which allows you to define such a mapping for you. In Entity Framework this gets much more complicated, but it's still in pretty in it's own way. The conceptual model allows you to include assembly-internal complex-types (as long as you tell the ObjectContext about it (ObjectContext.CreateProxyTypes(Type[])). So you can create a wrapper for your original type, that is only known to the Entity Framework like so:

 class Document : IXmlSerializable { }
 class Article
 {
     public virtual Document Content { get; set; }
 }
 internal class EntityFrameworkDocument : Document
 {
     public string Xml
     {
         get
         {
              // Use XmlSerializer to generate the XML-string for this instance.
         }
         set
         {
              // Use XmlSerializer to read the XML-string for this instance.
         }
     }
 }

Altough the EF can now return those serialized documents from the storage, writing them to it, requires you to intercept the storing of an Article and replace a simple Document with the EntityFrameworkDocument one, to ensure that EF can serialize it. I'm sure other ORMs does that pretty easily and it get's worse. Currently there is no way, to do the same with System.Uri class (which is immutable, but would otherwise work) or an Enum. Apart from those restrictions you can fit the EF to most of your needs. But you will spend a lot time on it (like I did).

Since my experience with other ORMs is limited, I would summarize:

  • Entity Framework is in the GAC, even in the Client Profile
  • Entity Framework can be customized to represent even complex entity types (Including some self-referencing many-to-many for example, or the the XML serialization above)
  • It can be "abstracted" away, so you can stick to IRepository etc.
  • IQueryable implementation (altough it's not that complete as DataObjects.Net)
  • It only requires System.Data and System.Data.Entity, you can even include multiple storage schemas for other providers which would normally require a reference, but if you stick to DbConnection you can just do this:

    ICatalog Create(DbConnection connection, string storageSchemaPath) ICatalog CreateMySql(DbConnection mySqlConnection) { return Create(connection, "res://Assembly/Path.To.Embedded.MySql.Storage.ssdl"); }

Edit I recently found out, that if your entities and your "catalog" implementation are in the same assembly, you can use internal properties for an XML serialization process. So instead of deriving an internal EntityFrameworkDocument from Document you could add an internal Property called Xml to the Document class itself. This still only applies if you have full control over your entities, but it removes the need to intercept any changes to the catalog, to make sure that your derived class is used. The CSDL looks the same, EF just allows the mapped property to be internal. I still have to ensure that this would work in Medium-Trust environments.


Hope fully these will help


When we use ADO.NET from scratch sooner or later we get frustrated and start looking for other solutions. I have tested many of them. Most of those ORM frameworks have lots of features and requires lots of knowledge. Some seem very easy at the beginning (eg: EF, Castle ActiveRecord) but there are many things you shall care about:

  • Caching
  • Many-to-many relationships
  • Lazy loading
  • Inheritance
  • Composite keys
  • How to encapsulate infratructure from callers
  • How SQL statements are generated
  • Performance
  • How to make advanced database queries

If you are an experienced developer and you are ready for all those pitfalls and stuffs then I ask you: Are your workmates also?

There are easier ways to code ADO.NET and not loose control of what is happening. Take a look at PainlessDAL.

"Elegant" coding is not always the best way.

참고URL : https://stackoverflow.com/questions/5101974/net-orm-comparison

반응형