为什么一个查询有效而另一个无效?

Mar*_*eke 7 c# linq entity-framework

我正在使用帮助方法根据用户访问权限预过滤我的所有查询.

假设方法签名为:

public IQueryable<Client> GetAllClients()
Run Code Online (Sandbox Code Playgroud)

使用LINQ时为什么这样做:

IQueryable<Client> allItems = GetAllClients();
return (from item in allItems
where item.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)
select item).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

但不是这个:

return (from item in GetAllClients() 
    where item.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)
    select item).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

我可以做第一个,但是离开LINQ几年之后,理解这个问题的原因会很好.

不工作我的意思是选项2给出了这个例外:

EntityFramework.SqlServer.dll中发生了'System.NotSupportedException'类型的第一次机会异常

附加信息:LINQ to Entities无法识别方法'System.Linq.IQueryable`1 [typename] GetAllClients()'方法,并且此方法无法转换为商店表达式.

客户端是存储在数据库中的数据类型.我正在为常用查询创建实体框架数据模型的方法,并且由于多租户设计具有由数据类型定义的安全访问,我想在数据访问级别进行过滤.

Dav*_*vid 7

这里的问题是可查询层正在尝试将方法调用GetAllClients转换为查询,而不是使用返回值GetAllClients作为查询源.语法上的欺骗,是的,但也完全是预期的.

之所以发生这种情况IQueryable,是因为与IEnumerables 不同,对象实际上呈现的是元代码,可用于将(在本例中)转换为SQL.由于大多数C#方法都没有SQL等价物,并且编译后的方法无法以相同的方式扫描其元序列,因此这些框架在遇到无法翻译的内容时会发生错误.

请注意,避免大部分问题的一种方法是避免使用Linq styntax,而是进行方法调用,这将稍微减少欺骗:

return GetAllClients()
    .Where(item => item.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)
    .FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

  • 您所说的通常适用于WHERE或SELECT子句,但我从未见过它会影响FROM.我认为这个问题还有更多. (3认同)