为啥 Linq-to-SQL 会添加不必要的 COUNT()?

Posted

技术标签:

【中文标题】为啥 Linq-to-SQL 会添加不必要的 COUNT()?【英文标题】:Why does Linq-to-SQL add unnecessary COUNT()?为什么 Linq-to-SQL 会添加不必要的 COUNT()? 【发布时间】:2017-08-15 03:08:47 【问题描述】:

这是我的桌子:

create table customer 
(
    cid int primary key,
    name varchar(32)
)

create table ord 
(
    oid int primary key,
    cid int foreign key references customer,
    address varchar(20)
)

这是我的 Linq-to-SQL 语句:

var aaa = from c in db.Customer
          select new  c, o = c.Ord.ToList() ;

这是由 Linq-to-SQL 生成的莫名其妙的查询:

SELECT 
    [t0].[cid] AS [Cid], [t0].[name] AS [Name], [t1].[oid] AS [Oid], 
    [t1].[cid] AS [Cid2], [t1].[address] AS [Address], 
    (SELECT COUNT(*)
     FROM [dbo].[ord] AS [t2]
     WHERE [t2].[cid] = [t0].[cid]) AS [value]
FROM [dbo].[customer] AS [t0]
LEFT OUTER JOIN [dbo].[ord] AS [t1] ON [t1].[cid] = [t0].[cid]
ORDER BY [t0].[cid], [t1].[oid]

我想了解如何摆脱 COUNT(*) 部分。这完全没有必要!

【问题讨论】:

可能相关? ***.com/questions/11997048/… 【参考方案1】:

LINQ 需要COUNT(*) 来确定将为o = c.Ord.ToList() 返回的条目数。

【讨论】:

为什么会有这种需求?他们不能在出现时继续扩展列表吗?我遇到的问题是这个查询生成了一个 N^2 的查询计划,其中 N 是每个客户的订单数(在我的情况下很大)。我对此感到非常沮丧。感谢您的洞察力。 考虑 SQL 如何返回数据 - 您有重复匹配的 t0(客户)字段与平面记录列表中的每个 t1(ord)字段匹配。 (SQL 只返回表。)不知何故,LINQ 必须创建一个客户记录,并与其中的 n 条记录合并。有可用的计数使这更容易。如果不查询每个客户的数据库以获取 ord 记录,我看不出如何以不同的方式完成。我假设您正在使用实体框架?如果您更改为 (from c in db.Customer select c).Include("ord") 会发生什么? 这是老式的 linq2sql,而不是 EF。我想象它是这样的:LINQ 正在读取传入的记录,并且对于每个记录,它都会创建一个新的 Customer 对象(如果之前没有创建),然后将结果行集的 Order 部分添加到相应的 Customer(通过客户 ID 查找) .无需知道您收到了多少订单 - 只需在收到订单时继续添加即可。哦,好吧。

以上是关于为啥 Linq-to-SQL 会添加不必要的 COUNT()?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Linq-to-sql 错误地删除了我的联合中的字段?

如何关联不同 dbml 图上的 Linq-To-Sql 对象?

在运行时将实体对象添加到 LINQ-to-SQL 数据上下文 - SQL、C#(WPF)

使用 Linq-to-SQL 的 ADO.NET 数据服务

为啥添加两个 .OrderBy(或 .OrderByDescending)语句会以相反的顺序应用排序?

Linq-To-Sql 尝试插入父实体而不是子实体