【问题标题】:EF linq statement not generating nested select count(*)EF linq 语句不生成嵌套选择计数(*)
【发布时间】:2020-01-30 18:06:06
【问题描述】:

我们有一个项目表,其中可以附加许多图像。我想创建一个端点,它返回所有项目以及附加到每个项目的图像数量作为 json。

我使用以下 linq 语句来做到这一点:

var items = context.Items.AsNoTracking ();
return Json (await items.Select (item => new {
    item = item,
    numImages = item.Images.Count (),
}).ToListAsync ());

这可行,但速度非常慢,因为 EF 会为每个项目生成一个单独的 SQL 语句,如下所示:

SELECT COUNT(*) FROM `Images` AS `q0` WHERE @_outer_IdImages = `q0`.`idImages`

如何构造我的 linq,以便只生成一个查询,如下所示:

SELECT idItems, name, (SELECT COUNT(*) FROM Images WHERE idItems = i.idItems) FROM Items i;

【问题讨论】:

  • 哪个 EF 版本?
  • 你在.Select()之前尝试过.Include(item => item.Images)吗?
  • @GertArnold 实体框架核心 2.2.6-servicing-10079
  • 使用 EF core 2,您必须解决变通办法。查询翻译的问题是压倒性的。我在 EF 3 中看到的情况变得更好了。一种解决方法可能是选择项目的属性,而不是项目本身。

标签: c# entity-framework linq .net-core linq-to-sql


【解决方案1】:

我通过生成图像字典解决了性能问题 idItems to Counts,如下:

var items = context.Items.AsNoTracking ();
var imagesDict = await context.Images.AsNoTracking ()
    .GroupBy (img => img.IdItems)
    .ToDictionaryAsync (g => g.Key, g => g.Count ());
return Json (await items.Select (item => new {
        item = item,
        numImages = imagesDict.GetValueOrDefault (item.IdItems, 0),
    }).ToListAsync ());

这根本不是我想要的,但它最终变得更快,因为只运行了两个 DbCommand。而且它比原始 SQL 干净得多

【讨论】:

  • 我开始提出这样的解决方案。避免在 LINQ 或原始 SQL 查询中键入所有 Item 的属性可能是您能做的最好的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-15
  • 2021-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多