Entity Framework 优化子实体计数
Entity Framework Optimize Count Child Entities
我正在尝试优化使用 Entity Framework Linq to SQL 查询生成的查询。以下是我的查询的大幅简化版本。
C#
List<bool> isUsed = Context.tParent.Select(parent =>
parent.tChild.Any()
).ToList();
这会产生以下结果 SQL
生成SQL
SELECT
CASE WHEN (( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[tChild] AS [Extent2]
WHERE [Extent1].[Id] = [Extent2].[ParentId]
))
) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1]
FROM [dbo].[tParent] AS [Extent1]
不幸的是,这表现不佳(我的真实查询检查许多链接表的计数),如果我按如下方式重写查询,速度会大大提高。
优化查询
SELECT CASE WHEN (
COUNT(tChild.Id) > 0
) THEN 1 ELSE 0 END
FROM tParent
LEFT JOIN tChild ON tParent.Id = tChild.ParentId
GROUP BY tParent.Id
如何重新编写 C# 以使用 Linq to SQL 查询生成优化的查询?
这个查询 return 所有 Parents 那至少一个 child:
var result = Context.tChild.Select(child => child.tParent)
.Distinct().ToList();
好吧,下面的 LINQ to Entities 查询有效地生成了与您的 优化查询 相同的 SQL。它基本上是 SQL 到 LINQ 翻译的一对一,但 IMO 描述查询目标的方式不是很直观。无论如何,这里是:
var query =
from parent in Context.tParent
from child in parent.tChild.DefaultIfEmpty()
group child by parent.Id into g
select g.Sum(child => child != null ? 1 : 0) > 0 ? true : false;
我正在尝试优化使用 Entity Framework Linq to SQL 查询生成的查询。以下是我的查询的大幅简化版本。
C#
List<bool> isUsed = Context.tParent.Select(parent =>
parent.tChild.Any()
).ToList();
这会产生以下结果 SQL
生成SQL
SELECT
CASE WHEN (( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[tChild] AS [Extent2]
WHERE [Extent1].[Id] = [Extent2].[ParentId]
))
) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1]
FROM [dbo].[tParent] AS [Extent1]
不幸的是,这表现不佳(我的真实查询检查许多链接表的计数),如果我按如下方式重写查询,速度会大大提高。
优化查询
SELECT CASE WHEN (
COUNT(tChild.Id) > 0
) THEN 1 ELSE 0 END
FROM tParent
LEFT JOIN tChild ON tParent.Id = tChild.ParentId
GROUP BY tParent.Id
如何重新编写 C# 以使用 Linq to SQL 查询生成优化的查询?
这个查询 return 所有 Parents 那至少一个 child:
var result = Context.tChild.Select(child => child.tParent)
.Distinct().ToList();
好吧,下面的 LINQ to Entities 查询有效地生成了与您的 优化查询 相同的 SQL。它基本上是 SQL 到 LINQ 翻译的一对一,但 IMO 描述查询目标的方式不是很直观。无论如何,这里是:
var query =
from parent in Context.tParent
from child in parent.tChild.DefaultIfEmpty()
group child by parent.Id into g
select g.Sum(child => child != null ? 1 : 0) > 0 ? true : false;