[英]Entity Framework, Repository pattern and let statements
嘗試使用Entity Framework實現正確的Repository模式,我對let語句的一些問題感到磕磕絆絆。 我想做的是:
var customer = (from cus in Customers.GetAll()
let brokerExists = InsuredBrokers.GetAll().Any(ib => ib.INS_Id == cus.INS_Id)
// ... more stuff
但這會給我一個錯誤
System.NotSupportedException: 'LINQ to Entities無法識別方法'System.Linq.IQueryable`1 [ SNIP .DataModel.EA_INB_InsuredBrokers_TB] GetAll()'方法,並且此方法無法轉換為商店表達式。
我可以做的是:
var customer = (from cus in Customers.GetAll()
let brokerExists = _context.Set<EA_INB_InsuredBrokers_TB>().Any(ib => ib.INS_Id == cus.INS_Id)
// ... more stuff
但是,這打破了使用Repository模式的任何一點。 當我搜索答案時,人們會說它自己把它放在查詢中並從內存中引用它,但由於我實際上在let語句中有客戶的Id( INS_Id
),所以我不能這樣做。
GetAll()
就像:
public IQueryable<T> GetAll()
{
return _context.Set<T>().AsQueryable();
}
有沒有聰明的方法來解決這個問題?
您必須將InsuredBrokers.GetAll()
移出查詢:
var allBrokers = InsuredBrokers.GetAll();
var customer = (from cus in Customers.GetAll()
let brokerExists = allBrokers.Any(ib => ib.INS_Id == cus.INS_Id)
// ... more stuff
然后它會正常工作。 由於GetAll
返回IQueryable
並且您沒有枚舉它 - 這沒有負面影響,並且仍然會有一個查詢到數據庫,就像在您的示例中使用_context
。
原因是let
語句編譯如下:
Customers.GetAll().Select(cus => new {cus, brokerExists = InsuredBrokers.GetAll().Any(ib => ib.INS_Id == cus.INS_Id)}
這意味着你對InsuredBrokers.GetAll()
調用是表達式樹的一部分(它在Select
表達式中),實體框架不能(不會)只是調用它來獲取值。 它會嘗試將其轉換為SQL查詢,但不知道如何處理GetAll
方法。
我假設您正在嘗試左連接。
您的查詢:
var query = from customer in Customers
join broker in InsuredBrokers
on customer.InsertId equals broker.InsertId
into resutGroups
select new { Name = broker.Name, InsertId= broker.InsertId};
如果您需要沒有匹配的條目,請使用DefaultIfEmpty 。
您可以參考這個更多關於一樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.