3

Entity Framework 6을 사용하고 도메인 기반 디자인을 학습하기 시작했습니다.LINQ to Entities가이 메서드를 인식하지 못함 - Entity Framework 및 DDD

DDD 원칙에 따르면 비즈니스 로직은 엔터티 및 값 개체의 도메인 계층에 있어야합니다.

public bool IsActiveInChat() 
{ 
    return this.ConnectedToChat && 
     (DateTime.Now - this.LastChatActivity).TotalMinutes < 10; 
} 

방법의 목적은에 표시 할 사용자를 필터링 할 수 있습니다 : 내 ApplicationUser 클래스에서

, 나는 사용자가 채팅에서 현재 활성화되어 있는지 여부를 밝히는 방법을 갖고 싶어 채팅 회원 목록.

입니다 ApplicationUserManager에서 쿼리, 인 Repository : 나는 쉽게 전송하여이 작업을 할 수

LINQ to Entities does not recognize the method 'Boolean IsActiveInChat()' method, and this method cannot be translated into a store expression.

:이 코드를 실행하면

public List<ApplicationUser> GetUsersConnectedToChat() 
{ 
    List<ApplicationUser> users = Users 
     .Where(u => u.IsActiveInChat()) 
     .ToList(); 

    return users; 
} 

, 나는 오류 논리를 Repository에 입력했는데 DDD에 대해 읽은 것부터 비즈니스 로직은 리포지토리가 아닌 엔티티에 속해야합니다.

이것은 (ApplicationUser의 방법없이) 동일한 쿼리의 작업 버전 :

public List<ApplicationUser> GetUsersConnectedToChat() 
{ 
    List<ApplicationUser> users = Users 
     .Where(u => u.ConnectedToChat && 
      DbFunctions.DiffSeconds(DateTime.Now, u.LastChatActivity) < 10) 
     .ToList(); 

    return users; 
} 

그래서, 내 질문 :이 엔티티 프레임 워크 알려진 문제입니다?

나는 오해하고 있습니까?

이 문제를 무시하고 비즈니스 로직을 User 엔티티에 보관할 수있는 방법이 있습니까?

P. - marc_s가 제기 한 질문은 내 질문에 답하지 않습니다. 첫째, 거기에 주어진 대답은 AsEnumerable을 사용하는 것이 좋습니다. 전체 테이블을 메모리로 가져오고 성능이 현저합니다. 또한이 문제에 대한 도메인 기반 디자인 접근 방식에 대한 내 질문에 답하지 못합니다.이 접근법은 상당히 일반적이며 프로젝트에서 많이 겪게 될 것입니다.

+1

[방법이 가게 표현으로 변환 할 수없는]의 사용 가능한 복제 (http://stackoverflow.com/questions/3846716/method-cannot-be-translated -into-a-store-expression) –

+0

이 질문이 중복되지 않은 이유를 설명하기 위해 제 질문을 편집했습니다. – Royar

+0

첫 번째 질문에 답하기 때문에 그렇습니다. 그리고 다른 질문은 너무 광범위합니다. EF 클래스 모델이 도메인 모델이라는 잘못된 가정을 먼저 논의해야하기 때문입니다. 그것은 DAL입니다. –

답변

3

이것은 일반적인 문제입니다.

필터링 논리가 C# 함수에 저장되어 있으면 SQL Server는 그것에 대해 아무 것도 모릅니다.

세 가지 옵션이 있습니다.

  1. 는 SQL에서 아래로 모든 데이터를 당겨 필터링을 수행 로컬 (이, 당신이 지적으로, 나쁜 성능으로 이어질 수 있습니다.)

  2. 은 전달 및 SQL 이해할 수있는 방식으로 필터링 로직을 작성하는

  3. 시도를 SQL로 필터링 논리를 이동

    .

3, 나는

Expression<Func<ApplicationUser, bool>> IsActiveInChat = r => 
    (r.ConnectedToChat.Value && (DateTime.Now - r.LastChatActivity).TotalMinutes < 10); 

또는 가능

Expression<Func<ApplicationUser, bool>> IsActiveInChat = r => 
     (r.ConnectedToChat && 
     DbFunctions.DiffSeconds(DateTime.Now, r.LastChatActivity) < 10) 

는 그런 다음

public List<ApplicationUser> GetUsersConnectedToChat() 
{ 
    List<ApplicationUser> users = Users 
     .Where(IsActiveInChat) 
     .ToList(); 

    return users; 
} 
으로이 기능을 사용할 수있는 것처럼 당신이 당신의 IsActiveInChat 기능을 다시 쓸 수있는 의미

이 방법의 문제점은 tha입니다. SQL에서 처리 할 수있는 함수에 국한됩니다. 당신이하려고하면 예를 들어, 당신은 NotSupportedException이 얻을 것이다

Expression<Func<ApplicationUser, bool>> isJan = r => 
    (r.LastChatActivity.ToSting("MMM") == "JAN"; 
+0

고마워요! 완전하고 도움이되는 대답. – Royar

관련 문제