ASP.NET MVC 응용 프로그램에서 Entity Framework를 모델로 직접 사용해야합니까?


22

Visual Studio 2013 (MVC 5)에서 첫 번째 MVC 응용 프로그램을 작성 중이며 모델을 설정하는 가장 좋은 방법이 명확하지 않습니다.

기존 데이터베이스에서 코드 우선을 사용하여 엔티티 프레임 워크 모델을 생성했습니다. 첫 번째 본능은 뷰에서 사용되는 모델이 될 중간 클래스를 만들고 해당 클래스가 엔터티 프레임 워크 클래스와 작동하도록하는 것입니다.

중개 클래스를 작성할 때 EF 클래스가 이미 가끔 개인 설정 도구로 수행했거나 한 데이터 유형에서 다른 데이터 유형으로 캐스트 된 많은 것들을 대부분 다시 구현하고 있음을 깨달았습니다. 그래서 그것은 낭비처럼 보였다.

엔티티 프레임 워크 클래스를 MVC 애플리케이션의 모델로 직접 사용하는 일반적인 규칙입니까? 아니면 이러한 중급 클래스를 구축 할 때 놓친 이점이 있습니까?



코드 우선을 사용했다면 기존 데이터베이스가 없었습니까?
Isaac Kleinman 1

1
EF 6.1+를 사용하면 기존 데이터베이스에서 코드 우선 모델을 생성 할 수 있습니다. 이 MSDN 기사 참조 : msdn.microsoft.com/en-au/data/jj200620.aspx
Mike D.

답변:


23

내 응용 프로그램에서 데이터베이스 (Entity Framework) 및 MVC에 대한 다른 모델을 사용하여 항상 항목을 분리했습니다. 나는 이것들을 다른 프로젝트로 분리했다.

  • Example.Entities -EF에 대한 엔티티 및 액세스를위한 DB 컨텍스트가 포함되어 있습니다.
  • . 모델-MVC 모델을 포함합니다.
  • . 웹-웹 애플리케이션. Example.Domain 및 Example.Models에 따라 다릅니다.

도메인 엔티티와 같은 다른 객체에 대한 참조를 보유하는 대신 MVC 모델은 ID를 정수로 보유합니다.

페이지에 대한 GET 요청이 들어 오면 MVC 컨트롤러는 데이터베이스 쿼리를 수행하여 엔터티를 반환합니다. 도메인 엔터티를 가져 와서 MVC 모델로 변환하는 "컨버터"메서드를 작성했습니다. MVC 모델에서 도메인 엔터티로 반대의 다른 방법이 있습니다. 그런 다음 모델이 뷰로 전달되어 클라이언트로 전달됩니다.

POST 요청이 들어 오면 MVC 컨트롤러는 MVC 모델을 가져옵니다. 변환기 메소드는이를 도메인 엔티티로 변환합니다. 이 방법은 또한 속성으로 표현할 수없는 모든 유효성 검사를 수행하며, 도메인 엔터티가 이미 존재하는 경우 새 속성을 얻는 대신 업데이트하고 있는지 확인합니다. 메소드는 일반적으로 다음과 같습니다.

public class PersonConverter
{
    public MyDatabaseContext _db;

    public PersonEntity Convert(PersonModel source)
    {
         PersonEntity destination = _db.People.Find(source.ID);

         if(destination == null)
             destination = new PersonEntity();

         destination.Name = source.Name;
         destination.Organisation = _db.Organisations.Find(source.OrganisationID);
         //etc

         return destination;
    }

    public PersonModel Convert(PersonEntity source)
    {
         PersonModel destination = new PersonModel()
         {
             Name = source.Name,
             OrganisationID = source.Organisation.ID,
             //etc
         };

         return destination;
    }
}

이 방법을 사용하여 각 컨트롤러에서 발생하는 중복을 제거합니다. 제네릭을 사용하면 상황이 더욱 중복 될 수 있습니다.

이 방법으로 작업하면 여러 가지 이점이 있습니다.

  • 모델을 특정보기 또는 동작으로 사용자 정의 할 수 있습니다. 제출할 때 다양한 엔티티 (사람, 조직, 주소)를 작성하는 사람에 대한 가입 양식이 있다고 가정하십시오. 별도의 MVC 모델이 없으면 매우 어려울 것입니다.
  • 엔터티에서만 사용할 수있는 것보다 더 많은 정보를 뷰에 전달하거나 두 엔터티를 단일 모델로 결합해야하는 경우 소중한 데이터베이스 모델은 절대 손대지 않습니다.
  • MVC 모델을 JSON 또는 XML로 직렬화 한 경우 다른 모든 엔티티가이 모델에 연결된 것은 아니지만 즉시 직렬화되는 직렬 모델 만 가져옵니다.

좋은 대답은 한 클래스에서 다른 클래스로 속성을 수동으로 매핑하는 대신 ValueInjector 또는 이와 유사한 것을 사용하는 것이 좋습니다 (개인적으로 오토 매퍼를 싫어했습니다).
Rocklan

1
여기서는 별도의 답변을 추가하는 대신 DDD 사례에서 뷰에 대한 "컨버터"와 별도의 모델이 응용 프로그램 서비스 계층의 일부로 간주 될 것입니다. 기본적으로 도메인 모델은 응용 프로그램에서 해당 복잡성을 숨기는 동시에 필요한만큼 복잡 할 수 있습니다. 또한 도메인 모델의 변경으로 인해 응용 프로그램을 변경하지 못하게합니다. ASL은 번역을 처리합니다.
Michael Brown

따라서 PersonModel에있는 각 모델 (예 : Organization 객체)을 호출하여 해당 모델의 정보를 얻습니까? 개인 및 조직 정보를 업데이트하는 양식이 있다고 가정합니다. 조직을 업데이트 할 때 추가 전화가 필요하십니까? 저장된 procs를 사용하고 있으므로 모든 모델 속성과 포함 된 모델 속성을 모두 한 번에 보낼 수 없습니까?
Luminous

1
컬렉션 매핑을 어떻게 처리합니까? 더 이상 모든 것을 다시 생성하기 때문에 업데이트로 새로운 엔티티 목록을 더 이상 만들 수 없기 때문에 EF6에서는 훨씬 더 복잡한 것 같습니다.
Gerard Wilkinson

2
자체 변환기 클래스를 작성하는 대신 이 문제를 해결하기 위해 작성된 Automapper 라이브러리를 사용하는 것이 좋습니다 . 2014 년부터 많이 성장했습니다!
BenSmith

6

나는 그것이 실제로 응용 프로그램에 달려 있다고 말합니다. 비즈니스 로직없이 순수한 CRUD를하고 있습니까? 그런 다음 EF 모델을 직접 사용합니다.

대부분의 경우 최소한 몇 가지 비즈니스 로직이 관련되어 있으며 데이터 / EF 모델과 뷰 사이에 계층이있는 것이 좋습니다. 이 경우 "CQRS-lite"(아래 참조)를 수행하고 컨트롤러 안팎으로 다른 모델을 사용하는 것이 적절할 수 있습니다. 대부분의 경우 읽기 모델은 쓰기 모델보다 훨씬 "더 빠릅니다".

그러나 응용 프로그램에 많은 비즈니스 논리가 포함되거나 확장이 필요한 경우 최소한 CQRS (Command Query Responsibility Segregation), DDD (Domain Driven Design) 및 가능하면 Event Sourcing을 사용하여 핵심을 구현해야합니다. 그런 다음 EF를 읽기 모델 파사드로 사용할 수 있습니다.

또한 전체 응용 프로그램에 대해 하나의 전략 / 패턴을 고수 할 필요가 없으며 일부 영역은 순수한 CRUD 일 수 있으며 다른 영역에는 많은 비즈니스 논리가 포함될 수 있습니다 ...

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.