繁体   English   中英

c#了解LINQ查询中的AsEnumerable

[英]c# Understanding AsEnumerable in LINQ query

代码如下:

var mids = _db.Members
     .GroupBy(m => new { m.MemberID, m.CreatedDate })
     .Where(m => m.All(s => s.Status == 1) && m.Key.CreatedDate.Date == DateTime.Today)
     .Select(m=>m);

我收到运行时错误:LINQ to Entities不支持指定的类型成员'Date'。 仅支持初始值设定项,实体成员和实体导航属性

当我将_db.Members.AsEnumerable()添加到它工作的第一行时。

我的理解是.AsEnumerable()强制查询在客户端执行。 所以在上面的代码中,AsEnumerable运算符将查询转换为2部分,在服务器端选择并在客户端休息(group by,where)。

有人可以验证我的理解是否正确? 以及没有.AsEnumerable()的代码失败的原因?

你的理解是正确的。 在调用AsEnumerable之后,无法再查询数据源,它又回到简单的“给我一切”模式,这意味着所有数据都被传输到客户端,任何进一步的操作都在本地完成。

这也是为什么查询不能正常工作的原因:为了使它工作,你在LINQ方法中使用的所有表达式都必须可以翻译成数据源所理解的任何语言 - 因为它是查询提供者有责任进行翻译,你也会受到编程支持的任何限制。

在这种特定情况下(假设为EF),可以通过手动将属性访问替换为规范函数TruncateTime来修复查询以在可查询模式下工作:

.Where(m => m.All(s => s.Status == 1) 
    && EntityFunctions.TruncateTime(m.Key.CreatedDate) ==
       EntityFunctions.TruncateTime(CurrentDateTime()))

当你想切换到LINQ to Objects时 ,经常使用AsEnumerable ,主要是因为你想使用Linq to Entities不支持的一些功能。 当您使用AsEnumerable() ,您正在转换为IEnumerable<T> ,它基本上将处理从数据源(具有所有数据和索引等)移动到您的应用程序。 换句话说,如果您不使用AsEnumerable()LINQ to Entities将把您的查询转换为SQL,它将在您的数据源中远程执行。 如果您想查看有关此主题的更多信息,我建议您阅读这篇文章

正如Jon所说, Entity Framework提供了一组函数来处理可以直接转换为SQL的日期,这些EntityFunctions位于EntityFunctions命名空间中。 这些映射到所谓的“规范函数”,这意味着SQL有1:1的转换

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM