簡體   English   中英

實體框架,存儲庫模式和let語句

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM