EF Core-转换为SQL简单选择

时间:2019-01-06 18:41:36

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

我有非常简单的模型

.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();

但是它向数据库发送两个查询

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]

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

1 个答案:

答案 0 :(得分:0)

您真的需要从MainImage和Images中选择*吗?总括可能会影响您的索引选择。在2.2中,您现在可以将投影与.ToList()一起使用,以仅选择所需的列。仍将对每个子集合使用单独的查询,但仅限于您投影到的列。

或者,由于您仅选择一行(由于在New Guid上的排序,因此是随机的),因此您可能能够显式地发出单独的请求,而在辅助查询中(在Images上)不需要排序。确实,由于每个查询都将使用不同的newid(),因此我怀疑在这种情况下您的图像结果无法正确对齐,因此您可能需要明确地进行操作。