2013-01-15 2 views
46

저는 Entity 프레임 워크를 사용하기 시작했습니다. 비즈니스 레이어의 클래스가 Entity Framework에서 생성 된 엔티티와 어떻게 잘 어울리는 지 혼란 스럽습니다. .Entity 프레임 워크를 사용할 때 비즈니스 로직을 어디에 둘 것인지 혼란합니다.

클래식 ADO.NET에서 작업 할 때 예를 들어 Customer라는 클래스를 사용하고 데이터베이스 상호 작용을 처리하기 위해 DALCustomer라는 다른 클래스를 사용할 수 있습니다.이 구조에서는 계산을 수행하고 인스턴스를 필터링하고 delcare하는 코드를 넣었을 것입니다 Customer 클래스에서 저장, 업데이트 및 삭제를 수행하는 DAL의 권한.

Customer라는 테이블이있는 경우 Entity 프레임 워크는 Customer라는 엔터티를 만들고 이것이 내 혼란이 시작되는 곳이며이 엔터티는 비즈니스 계층에서 Customer의 필요성을 제거합니까? 본질적으로 비즈니스 계층에서 일반적으로 사용되는 모든 필드와 메서드는 Entity Framework에서 생성 된 엔터티에 포함됩니까? 또는 계산, 필터링에 필요한 비즈니스 로직을 수행하는 데 필요한 필드와 메서드를 여전히 포함하고 있으며 데이터 액세스를 처리하도록 선언 된 EF DAL의 인스턴스가 여전히 필요한 클래스가 CustomerBL이라는 비즈니스 계층에 여전히 있어야합니다.

비즈니스 클래스 (이 경우 CustomerBL)가 있어야하는 경우 고객 엔터티에서 생성 된 필드가 CustomerBL에서 다시 작성되거나 Customer 엔터티의 인스턴스가 CustomerBL 그래서 2 개 장소에서 필드를 선언 할 필요가 없을 것입니다.

답변

5

가 다른 사람에 의해 좋은 실례로 간주하지만 난 과거에이 문제를 처리하는 방법을 개인적으로 이것이 않다면 나도 몰라 : EF에 의해 생성

수업이 DAL이며, 다음 BL이 보완 세트를 생성하기위한 필요한 구조 (예 : 일대일 관계에서 관련 엔터티의 데이터를 병합하는 것과 같음) 및 기타 비즈니스 로직 관련 문제가 처리되는 클래스 (예 : IDataErrorInfo 구현과 같은 사용자 지정 유효성 검사가 UI의 WPF 또한 BL 인스턴스를 사용하고 EF 엔티티와 BL 개체를 서로 변환하는 엔티티 유형과 관련된 모든 비즈니스 계층 메서드를 포함하는 클래스를 만듭니다.

예를 들어 db에 고객이 있습니다. EF는 고객 클래스를 생성하고 BL에는 고객 (접두어, 접미사 등) 클래스 및 CustomerLogic 클래스가 있습니다. BL Customer 클래스에서는 EF 엔티티를 변경하지 않고도 BL 메서드 (가장 가치있는 고객로드, 추가 데이터로 고객 저장 등)를 수행하는 CustomerLogic 클래스를 변경하지 않고도 요구 사항을 충족하는 데 필요한 모든 작업을 수행 할 수 있습니다.

이제 데이터 소스 구현에 느슨하게 결합 할 수 있습니다. 과거 WPF 프로젝트에서 나에게 많은 혜택을 주었던 또 다른 예는 IDataErrorInfo를 구현하고 CustomerBL 클래스에 유효성 검사 로직을 구현하는 등의 작업을 수행 할 수 있으므로 UI의 작성/편집 양식에 엔터티를 바인드 할 때 WPF에서 제공하는 기본 제공 기능을 활용할 수 있습니다.

... 내 2 센트, 나는 또한 모범 사례 또는 다른 솔루션/관점이 무엇인지 궁금하다.


은 또한 아마이 주제와 관련된 - Code-first vs Model/Database-first

+0

EF에서 생성되고 BL 클래스에 필요한 필드는 어떻게 처리합니까? 약간의 샘플을 제공 할 수 있습니까? –

+1

글쎄, 내가 BL/DAL 엔티티에서 /로 데이터를 복사하는 메소드가 필요하다는 것과 DAL에서 액세스하지 못하도록 리포지토리 패턴을 구현하는 방법이 필요하다는 사실에서 빠져있다. ObjectSet 자체를 직접 호출하는 대신 CRUD 작업을위한 저장소를 호출합니다. – dutzu

+0

부분 클래스는이를 처리하는 방법입니다. –

24

엔티티 프레임 워크, LINQ - 투 - SQL을 예를 들어 반대로, 데이터 모델과 마음의 개념 모델 사이의 분리 설계되었습니다.inheritance, entity splitting, table splitting, complex typestransparent many-to-many associations을 지원하며 모두 데이터 저장소 모델에 너무 많은 제약을받지 않고 도메인 모델을 필요에 맞게 성형 할 수 있습니다.

코드 우선 접근 방식을 사용하면 선택한 속성을 데이터 저장소 열에 매핑 할 수있는 POCO를 사용하여 작업 할 수 있습니다. 모델 우선 및 데이터베이스 우선 부분 클래스를 생성하여 생성 된 코드를 확장 할 수 있습니다. 이 클래스들로 작업하는 것은 POCO와 함께 일하는 모양과 느낌을 가지고 있습니다. 버전 5 이후로 DbContext이 기본 API가되었을 때 생성 된 클래스는 더 이상 ObjectContext API의 지속성 관련 코드로 채워지지 않았습니다.

물론이 개념 모델과 상점 모델의 분리는 어느 정도 성공할 수 있습니다. 일부 목표는 지속성 무지이라는 목표에 부합합니다. 예를 들어 지연로드가 바람직한 경우 탐색 속성을 virtual으로 선언해야하므로 EF가 프록시 유형에서이를 무시할 수 있습니다. 그리고 "실제"연관 (Parent 참조)에 수반되는 원시 외래 키 속성 (예 : ParentId)을 갖는 것이 편리한 매우입니다. 순수 주의자들은 이것이 도메인 중심 디자인을 위반한다고 생각합니다.

지속성에 대한 또 다른 중요한 위반은 differences between linq-to-objects and linq-to-entities입니다. 메모리에있는 객체와는 완전히 다른 우주에 맞서고 있다는 사실을 그냥 무시할 수는 없습니다. 이를 tight coupling, or leaky abstraction이라고합니다.

하지만 ... 일반적으로 생성 된 EF 클래스 또는 코드 우선 모델의 POCO를 도메인 클래스로 사용하면 만족합니다. 지금까지 전혀 데이터 저장소에서 다른 저장소로 마찰이없는 전환을 본 적이 없습니다. 영속성의 무지는 허구입니다. DAL의 특성은 항상 도메인에 발자국을 남깁니다. 다른 데이터 저장소/모델을 코딩해야하거나 상점/모델이 비교적 자주 변경 될 것으로 예상되는 경우에만이 공간을 가능한 한 최소화하거나 완전히 추상화하는 것이 좋습니다.

또 다른 요소는 EF 클래스를 도메인 클래스로 승격시킬 수 있다는 것입니다. 오늘날 여러 응용 프로그램이 (직렬화 된) 다른 뷰 모델 또는 DTO가 클라이언트로 전송되는 여러 계층을가집니다. UI에서 도메인 클래스를 사용하는 것은 법안에 거의 부합하지 않습니다. EF 클래스를 도메인으로 사용할 수도 있고 UI 또는 서비스 소비자가 요구하는 전용 모델 및 DTO를 제공하는 서비스를 가질 수도 있습니다. 퍼포먼스 측면에서만 다른 추상화 계층은 축복보다 부담이 될 수 있습니다.

+0

EF가 넣는 것에 의존하려는 유혹에 저항합니다. INotifyPropertyChanged'? 필요한 경우 t4 템플릿을 수정하여 이와 같은 것을 구현할 수 있습니다. –

+0

물론 수정할 수 있습니다. 나는 EF로 생성 된 속성과 메서드를 사용하면 지속성에 대한 무지를 훨씬 더 깨뜨릴 수 있다는 것을 의미합니다. 표준 템플릿은 새 버전으로 변경 될 수 있습니다. –

+4

Gert, 무례한 의도는 없지만 내 수준에서 나와 함께 할 수 있을지, 아마도 내가 완전히 새로운 것에 빠지기 때문에 내가 너에게 완전히 뒤 따르지 않고있는 것처럼 내 원래 게시물의 예에 당신이 말하는 말을 어떻게 적용 할 수 있겠는가? EF. –

13

내 견해로는 POCO를 지속 가능한 엔터티로 사용하는 것이 "데이터베이스 엔터티"와 "비즈니스 엔터티"의 구분을 제거하는 것입니다. "엔티티"는 데이터 저장소에서 직접 유지되고로드 될 수 있으므로 동시에 "데이터베이스 엔터티"로 작동하는 "비즈니스 엔터티"로 간주됩니다. POCO를 사용하여 비즈니스 엔티티는 특정 메커니즘에서 분리되어 데이터베이스와 상호 작용합니다.

엔티티를 다른 프로젝트 (예를 들어)로 이동할 수 있습니다.이 프로젝트에는 EF 어셈블리에 대한 참조가없고 데이터베이스 계층 프로젝트에서 지속성을 관리하는 데 사용됩니다.

이것은 EF에 대한 요구 사항을 염두에 두지 않고 비즈니스 엔티티를 완전히 설계 할 수 있음을 의미하지 않습니다.

  • 당신은 다른 참조 탐색 속성 (참조 또는 컬렉션을해야합니다 : 당신은 당신이 예를 들어, EF를 사용하여 데이터베이스 스키마에 대한 비즈니스 엔티티를 매핑하는 점에 올 때 문제를 방지하기 위해 알아야하는 제한이 있습니다 엔터티) 은 EF로 지연로드를 지원합니다.
  • 보존해야하는 모음에는 IEnumerable<T>을 사용할 수 없습니다. ICollection<T>이거나 더 파생 된 형식이어야합니다.
  • 그것은 ... private 속성
  • 유형 char는 EF에서 지원하지 않는 당신이 그 값
  • 등을 유지하려는 경우 당신이 그것을 사용할 수 없습니다를 유지하는 것은 쉽지 않다

그러나 엔티티의 추가 세트는 - 내 의견으로는 - 언급 된 제한 사항이 프로젝트에 너무 엄격한 경우 실제로 필요하기 위해 정당화되어야하는 복잡성의 추가 레이어입니다.

YA2C (또 다른 2 센트 :)

+3

나는 이것에 동의한다. ORM의 기본 메커니즘은 엔티티 자체가 아니라 데이터 계층을 '대체'한다. MVC 타입의 어플리케이션에서 필자는 필요에 따라 Entity에서 파생되지 않은 특정 정보를 표현하기 위해 ViewModel을 별도로 생성 할 수 있습니다. OP와 마찬가지로 나는 때때로이 항해가 어려워 보인다. – Matthew

0
과 기술 중심의 디자인을 통해 DDD (도메인 기반 설계를) 사용의 우려를 지적

내 방법과 수익을 작성하는 비즈니스 로직을 사용 결과는 다음과 같습니다.

namespace Template.BusinessLogic 
{ 
    public interface IApplicantBusiness 
    { 
     List<Template.Model.ApplicantView> GetAllApplicants(); 

     void InsertApplicant(Template.Model.ApplicantView applicant); 
    } 
} 
관련 문제