C# 是否可以在对Where的调用中调用命名方法?

C# 是否可以在对Where的调用中调用命名方法?,c#,.net,linq,entity-framework-4,linq-to-entities,C#,.net,Linq,Entity Framework 4,Linq To Entities,我试图从红门的这本免费电子书中了解Linq的一些性能含义 在本书第157-158页,他们创建了以下示例 Order[] pastDueAccounts = null; DateTimedueDate = DateTime.Today.AddDays(-7); using(varcontext = new Context()) { pastDueAccounts = context.Accounts.Where(account => account.DueDat

我试图从红门的这本免费电子书中了解Linq的一些性能含义

在本书第157-158页,他们创建了以下示例

Order[] pastDueAccounts = null;  
DateTimedueDate = DateTime.Today.AddDays(-7);  
using(varcontext = new Context())    
{  
    pastDueAccounts = context.Accounts.Where(account => account.DueDate < dueDate).ToArray();  
} 

根据我到目前为止的研究,不可能运行此linq查询,因为linq将无法识别该方法,并且无法转换为存储表达式。我想知道这个例子是否是错误的,根本不可能运行,或者我只是很难让大家了解如何模拟这个问题?

正如casperOne所说,你不能用函数来实现这一点。这个答案是一种完成您需要做的事情的方法(重用where过滤器)

您可以在可以访问的地方创建一个
表达式
,然后重用它

System.Linq.Expressions.Expression passdueaccountfunc=account=>account.DueDate

然后在以后使用它:

var passdueaccounts=context.Accounts.Where(passdueaccountfunc)

这是我使用的完整代码:

System.Linq.Expressions.Expression<Func<SomeNeatEntity, bool>> func = x => x.DateCreated < System.Data.Objects.EntityFunctions.AddDays(DateTime.Now, -7);

var entities = new MyEntities();

var t = entities.SomeNeatEntities.Where(func);
Console.WriteLine(t.Count());

var h = entities.SomeNeatEntities.Where(x => x.SomeField != null).Where(func);
Console.WriteLine(h.Count());
System.Linq.Expressions.Expression func=x=>x.DateCreatedx.SomeField!=null)。Where(func);
Console.WriteLine(h.Count());
MyEntities
是项目中的
ObjectContext


实体。某些实体
对象集

如果您是正确的,LINQ将无法按其显示方式调用实体

在LINQ to实体中使用它的唯一方法是:

  • 在服务器端创建等效的函数
  • 正确地翻译调用

这是错误的,也不会起作用,因为这不是lambda表达式,查询提供程序无法对其进行计算。如果它起作用,则您正在客户端上进行筛选,而对
的调用,其中
正在评估
IEnumerable
的结果,而不是将筛选器转换到服务器端。请记住,
IQueryable
源于
IEnumerable
,因此,
IEnumerable
上的所有扩展方法都将在
IQueryable
上工作,并且在转换发生的位置并不总是很明显。我直接在EF上下文中使用func。它对我起作用纯粹是因为我在同一个代码块中拥有所有扩展方法吗?对于查询
t
SomeNeatEntities
中的所有实体都通过网络传输过来,然后在客户端上过滤掉。在查询
h
中,对
Where
的第一次调用被转换为SQL,其结果通过对
Where
的第二次调用进行过滤。如果您将鼠标悬停在VS.NET中的
Where
方法上,您将看到对于
t
和第二个
Where
调用
h
,它调用的是
Enumerable.Where
,但在
h
上第一次调用
Where
时,它调用的是
Queryable.Where
,并且lambda表达式是
表达式
;其他的是委托。使用LINQKit的
AsExpandable()
是另一种选择,您可以使用能够转换为SQL的表达式方法。@casperOne:关于您在VS.NET中悬停在where上对t和h调用where的评论,它如何确定何时使用IEnumerable调用Where以及何时使用IQueryable调用Where?@palmsnow基本上是通过类型推断确定最佳匹配。在这种特殊情况下,由于参数是
Func
而不是
表达式
,因此它不能与
可查询项相匹配。其中
(接受表达式),只有
可枚举。其中
(接受委托)。
Order[] pastDueAccounts = null;  
using(varcontext = new Context())  
{  
    pastDueAccounts = context.Accounts.Where(account => PastDueAccount(account)).ToArray();  
} 
System.Linq.Expressions.Expression<Func<SomeNeatEntity, bool>> func = x => x.DateCreated < System.Data.Objects.EntityFunctions.AddDays(DateTime.Now, -7);

var entities = new MyEntities();

var t = entities.SomeNeatEntities.Where(func);
Console.WriteLine(t.Count());

var h = entities.SomeNeatEntities.Where(x => x.SomeField != null).Where(func);
Console.WriteLine(h.Count());