[英]Entity Framework, Repository pattern and let statements
Trying to implement a correct Repository pattern with Entity Framework, I'm stumbling over some issues with let statements. 尝试使用Entity Framework实现正确的Repository模式,我对let语句的一些问题感到磕磕绊绊。 What I want to do is:
我想做的是:
var customer = (from cus in Customers.GetAll()
let brokerExists = InsuredBrokers.GetAll().Any(ib => ib.INS_Id == cus.INS_Id)
// ... more stuff
But this will give me an error 但这会给我一个错误
System.NotSupportedException: 'LINQ to Entities does not recognize the method 'System.Linq.IQueryable`1[ SNIP .DataModel.EA_INB_InsuredBrokers_TB] GetAll()' method, and this method cannot be translated into a store expression.'
System.NotSupportedException: 'LINQ to Entities无法识别方法'System.Linq.IQueryable`1 [ SNIP .DataModel.EA_INB_InsuredBrokers_TB] GetAll()'方法,并且此方法无法转换为商店表达式。
What I instead can do is: 我可以做的是:
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
However, this breaks any point in using the Repository pattern. 但是,这打破了使用Repository模式的任何一点。 When I search for answers, people say to put it in a query on its own and reference it from memory, but since I actually have the customer's Id (
INS_Id
) in the let statement, I cannot do that. 当我搜索答案时,人们会说它自己把它放在查询中并从内存中引用它,但由于我实际上在let语句中有客户的Id(
INS_Id
),所以我不能这样做。
GetAll()
is like: GetAll()
就像:
public IQueryable<T> GetAll()
{
return _context.Set<T>().AsQueryable();
}
Are there any clever ways to get around this? 有没有聪明的方法来解决这个问题?
You have to move InsuredBrokers.GetAll()
out of the query: 您必须将
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
Then it will work fine. 然后它会正常工作。 Since
GetAll
returns IQueryable
and you don't enumerate it - this has no negative effect and there will still be one query to database, just like in your example with _context
. 由于
GetAll
返回IQueryable
并且您没有枚举它 - 这没有负面影响,并且仍然会有一个查询到数据库,就像在您的示例中使用_context
。
The reason is let
statement is compiled like this: 原因是
let
语句编译如下:
Customers.GetAll().Select(cus => new {cus, brokerExists = InsuredBrokers.GetAll().Any(ib => ib.INS_Id == cus.INS_Id)}
Which means your call to InsuredBrokers.GetAll()
is part of expression tree (it's inside Select
expression), and entity framework cannot (will not) just call it to obtain value. 这意味着你对
InsuredBrokers.GetAll()
调用是表达式树的一部分(它在Select
表达式中),实体框架不能(不会)只是调用它来获取值。 It will try to translate it to SQL query, but has no idea what to do with GetAll
method. 它会尝试将其转换为SQL查询,但不知道如何处理
GetAll
方法。
I assume you are trying to do a left join. 我假设您正在尝试左连接。
Your query: 您的查询:
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};
If you need entries for no maches use DefaultIfEmpty . 如果您需要没有匹配的条目,请使用DefaultIfEmpty 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.