【问题标题】:EF Core - translating to SQL simple selectEF Core - 转换为 SQL 简单选择
【发布时间】:2019-01-06 18:41:36
【问题描述】:

我有非常简单的模型

.NET Core 2.1 / EF Core 2.1 / MSSQL

public class ImageZ
{
    [Key]
    public Guid Id { get; set; }
    public string Base64 { get; set; }
    public string Title { get; set; }
}

public class Gallery
{
    [Key]
    public Guid Id { get; set; }
    public ImageZ MainImage { get; set; }
    public List<ImageZ> Images { get; set; } = new List<ImageZ>();
}

我正在使用这个 LINQ 从 db 加载它

return _context
       .Gallery
       .Include(x => x.Images)
       .Include(x => x.MainImage)
       .OrderBy(x => Guid.NewGuid())
       .FirstOrDefault();

但它会向 db 发送两个查询

SELECT TOP(1) [x].[Id], [x].[MainImageId], [x.MainImage].[Id], [x.MainImage].[Base64], [x.MainImage].[GalleryId], [x.MainImage].[Title]
FROM [Gallery] AS [x]
LEFT JOIN [ImageZ] AS [x.MainImage] ON [x].[MainImageId] = [x.MainImage].[Id]
ORDER BY NEWID(), [x].[Id]

SELECT [x.Images].[Id], [x.Images].[Base64], [x.Images].[GalleryId], [x.Images].[Title]
FROM [ImageZ] AS [x.Images]
INNER JOIN (
    SELECT DISTINCT [t].*
    FROM (
        SELECT TOP(1) [x0].[Id], NEWID() AS [c]
        FROM [Gallery] AS [x0]
        LEFT JOIN [ImageZ] AS [x.MainImage0] ON [x0].[MainImageId] = [x.MainImage0].[Id]
        ORDER BY [c], [x0].[Id]
    ) AS [t]
) AS [t0] ON [x.Images].[GalleryId] = [t0].[Id]
ORDER BY [t0].[c], [t0].[Id]

这是正确的行为吗?不应该只用一个吗?

【问题讨论】:

  • 不,实际上这是一个很大的改进。在 EF6 中,很容易包含多个 blow up the SQL result set both in length and in width。执行多个相对较小的查询可以防止这种情况。性能的关键是查询是在一批中执行的。
  • @GertArnold 那么,我不应该尝试从这个 LINQ 中获得更好的东西吗?
  • 不,让 EF 自己动手。如果你操纵它,当 EF 以后让它变得更好时,你就完蛋了。

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


【解决方案1】:

你真的需要从 MainImage 和 Images 中选择 * 吗?一揽子包含可能会对您的索引选择产生影响。在 2.2 中,您现在可以使用带有 .ToList() 的投影来仅选择您需要的列。它仍将对每个子集合使用单独的查询,但仅限于您投影到的列。

另外,由于您只选择一行(由于新 Guid 上的 order by 随机),您可能能够显式发出单独的请求,并且不需要在辅助查询中 order by(通过图像)。实际上,由于每个查询都将使用不同的 newid(),我怀疑在这种情况下您的图像结果将无法正确对齐,您可能需要明确地进行对齐。

【讨论】:

  • 嗯,有什么例子可以说明我如何以不同的方式做到这一点?或者“MainImage”应该只是 Image 的一个 ID,而不是将它放在这个属性中,而是将它移到图像列表中?
猜你喜欢
  • 2020-04-24
  • 1970-01-01
  • 2020-06-14
  • 1970-01-01
  • 2021-09-05
  • 2020-08-22
  • 2020-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多