LINQ对实体看似奇怪的行为
我有一个Linq查询,它非常奇怪地转换为SQL。我得到了正确的结果,但一定有更好的方法。因此,问题1是: 为什么在SQL中我没有GROUPBY、count和所有 返回列,而不是仅返回2列;那么C中的结果是正确的吗?我和探查器核对过了。 问题2是: 我想稍微修改一下查询,这样我也可以得到 计数为0的结果。目前我只得到计数大于0的值 因为这群人。 林克:LINQ对实体看似奇怪的行为,linq,group-by,linq-to-entities,Linq,Group By,Linq To Entities,我有一个Linq查询,它非常奇怪地转换为SQL。我得到了正确的结果,但一定有更好的方法。因此,问题1是: 为什么在SQL中我没有GROUPBY、count和所有 返回列,而不是仅返回2列;那么C中的结果是正确的吗?我和探查器核对过了。 问题2是: 我想稍微修改一下查询,这样我也可以得到 计数为0的结果。目前我只得到计数大于0的值 因为这群人。 林克: 注意,如果在中间删除.TLIST,则只在LINQ实体中支持无参数的构造函数和初始化器。 感谢您的投入您遇到了几个问题。我认为这是因为您没有意识到可
注意,如果在中间删除.TLIST,则只在LINQ实体中支持无参数的构造函数和初始化器。
感谢您的投入您遇到了几个问题。我认为这是因为您没有意识到可计算查询和可查询查询之间的区别 可计算查询包含要在查询中的元素上枚举的所有信息。查询将由您的进程执行 可查询查询,包含表达式和提供程序。提供者知道谁将执行查询,以及如何与该执行者通信。通常,执行器是数据库,但也可以是其他东西,如internet查询、jswon文件等 在您的情况下,执行器将是一个数据库,语言将是SQL 调用IQueryable的GetEnumerator函数时,将命令提供程序将表达式转换为执行者知道的语言。翻译后的查询被发送给执行器,返回的数据被放入一个不可IEnumerable的枚举器中 当然,SQL不知道System.Tuple是什么,也不知道String.operator之类的函数+ 因此,提供程序无法将表达式转换为SQL。这就是为什么你要做你的第一个托利表 您不能使用自己的任何函数进行IQueryable查询,只能使用有限数量的.NET函数 不建议在此查询中使用ToList,因为它枚举了序列中的所有元素,实际上您只需要一个枚举器。可能在查询的其余部分中,您只需要几个元素。在这种情况下,对所有这些进行枚举以创建一个列表,然后再次枚举以完成LINQ的其余部分将是一种浪费 而不是使用托利斯。这将把查询的所有数据带到本地内存,并创建一个IEnumerable:元素还没有被枚举。这将允许您在查询的其余部分调用本地函数 另一个问题是,向本地内存传输的数据比您计划使用的要多。数据库查询中较慢的部分之一是将数据传输到进程。您应该尽量减少数据量 您接受了所有审核,并创建了具有相同类型CreatedBy值的审核组。换句话说:同一组中的所有审核都具有相同的类型CreatedBy值。该值也是组的键 您不希望所有审核都在本地进行,只希望组的键和该组的元素数=类型为CreatedBy的审核数等于键 这是您需要传输到本地内存的唯一数据:Type、CreatedBy和组中的审核数:
var result = db1.Audits.GroupBy(o => new { o.Type, o.CreatedBy })
.Select(group => new
{
Type = group.Key.Type,
CreatedBy = group.Key.CreatedBy,
AuditCount = group.Count(),
})
.OrderBy(item => item.CreatedBy)
// the data that is left is the data you need locally
// bring to local memory:
.AsEnumerable()
// if you want you can put Type and CreatedBy into one string
.Select(item => new
{
AuditType = item.Type + item.CreatedBy,
AuditCount = item.AuditCount,
});
我选择不将结果放入元组,因为如果混淆字段,将失去编译器的帮助。但如果你真的想适合自己 谢谢Harald。我知道这两种情况,但不太习惯它们,因此我并不立即意识到这一点。这是有道理的,当然我不想加载所有结果,只想加载这3个结果。关于我的第二个问题,你有什么想法吗?对于第二个问题,你需要将你的审计表与所有创建者的表以及所有类型的表进行完整的外部连接。通过这种方式,您可以包括所有从未创建审核的创建者,以及所有从未审核过的类型。Linq不知道完全外部联接。在stackoverlow上有几种解决方案
var result = db1.Audits.GroupBy(o => new { o.Type, o.CreatedBy })
.Select(group => new
{
Type = group.Key.Type,
CreatedBy = group.Key.CreatedBy,
AuditCount = group.Count(),
})
.OrderBy(item => item.CreatedBy)
// the data that is left is the data you need locally
// bring to local memory:
.AsEnumerable()
// if you want you can put Type and CreatedBy into one string
.Select(item => new
{
AuditType = item.Type + item.CreatedBy,
AuditCount = item.AuditCount,
});