C# 是否可以在对Where的调用中调用命名方法?
我试图从红门的这本免费电子书中了解Linq的一些性能含义 在本书第157-158页,他们创建了以下示例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
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());