2016-11-26 102 views
3

我開始使用Entity Framework 6並學習Domain Driven Design。LINQ to Entities無法識別該方法 - 實體框架和DDD

據我瞭解,根據DDD原則,業務邏輯應該駐留在領域層,在實體和值對象。

在我ApplicationUser類,我想有說該用戶是否爲當前在聊天活躍的方法:

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

方法的目的是來過濾顯示哪些用戶聊天成員列表。

這是ApplicationUserManager查詢,這是Repository

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

    return users; 
} 

當我運行這段代碼,我得到的錯誤:

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

我可以很容易地通過轉移,使這項工作邏輯到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.S. - 由marc_s提出的問題不回答我的問題。首先,在那裏給出的答案建議使用AsEnumerable,它將整個表提取到內存中,並且性能不佳。它也沒有回答我對這個問題的領域驅動設計方法是什麼的問題,這個問題看起來很常見,而且在我的項目中我會遇到很多問題。

+1

[方法不能被翻譯成店表情]可能的複製(http://stackoverflow.com/questions/3846716/method-cannot-be-translated -into-store-expression) –

+0

我編輯了我的問題來解釋爲什麼這不是重複的。 – Royar

+0

這是因爲它回答你的第一個問題。其他問題太廣泛了,因爲他們首先需要討論EF類模型是領域模型的錯誤假設。這是一個DAL。 –

回答

3

這是一個常見問題。

如果您的篩選邏輯存儲在C#的功能,那麼SQL Server不知道這件事。

您有三種選擇。

  1. 所有的數據從SQL拉下,並執行過濾本地 (正如你所指出的,可能會導致不好的性能)。

  2. 移動您的過濾邏輯到SQL

  3. 嘗試寫入的濾波 邏輯可以傳遞到和由SQL理解的方式。

到3,我的意思是你可以重新寫你的IsActiveInChat功能像

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; 
} 

這種方法的問題在於你僅限於SQL可以處理的函數。例如,如果你嘗試,你會得到一個NotSupportedException異常

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

謝謝!一個完整而有用的答案。 – Royar

相關問題