【发布时间】:2015-04-07 00:21:31
【问题描述】:
我将 EF 与代码优先和迁移一起使用。我有两个实体:
public class LicensedSoftware
{
public int Id { get; set; }
public int ResourceId { get; set; }
public int SoftwareDetailId { get; set; }
}
public class SoftwareDetail
{
public int Id { get; set; }
public string FamilyName { get; set; }
public string SoftwareName { get; set; }
public string Version { get; set; }
}
我正在尝试指定在进行左外连接时要依靠的列,但它似乎只使用Count(*)。
这是我的 linq:
SoftwareDetails
.GroupJoin(LicensedSoftwares, l => l.Id, c => c.SoftwareDetailId,
(l, c) =>
new { Licensed = l, Details = c.DefaultIfEmpty() })
.SelectMany(x => x.Details, (x, merged) => new { Details = merged, x.Licensed })
.GroupBy(x => x.Licensed, x => x.Details,
(key, g) =>
new { Licensed = key, Count = g.Count() })
生成的SQL是:
SELECT COUNT(*) AS [Count]
, [t0].[Id], [t0].[FamilyName], [t0].[SoftwareName], [t0].[Version]
FROM [SoftwareDetails] AS [t0]
LEFT OUTER JOIN [LicensedSoftwares] AS [t1] ON [t0].[Id] = [t1].[SoftwareDetailId]
GROUP BY [t0].[Id], [t0].[FamilyName], [t0].[SoftwareName], [t0].[Version]
这也将计算 SoftwareDetails 表中的行,因此我的计数始终至少为 1。
我希望它是(注意选择中的计数):
SELECT COUNT([t1].[Id]) AS [Count]
, [t0].[Id], [t0].[FamilyName], [t0].[SoftwareName], [t0].[Version]
FROM [SoftwareDetails] AS [t0]
LEFT OUTER JOIN [LicensedSoftwares] AS [t1] ON [t0].[Id] = [t1].[SoftwareDetailId]
GROUP BY [t0].[Id], [t0].[FamilyName], [t0].[SoftwareName], [t0].[Version]
我得到的最接近正确结果的是:
SoftwareDetails
.Select (sd => new
{
sd.Id, sd.FamilyName, sd.SoftwareName, sd.Version,
Count = LicensedSoftwares
.Where(ls => ls.SoftwareDetailId == sd.Id && ls.Id != null)
.Count()
})
但我不喜欢它生成的 SQL:
SELECT [t0].[Id], [t0].[FamilyName], [t0].[SoftwareName], [t0].[Version], (
SELECT COUNT(*)
FROM [LicensedSoftwares] AS [t1]
WHERE [t1].[SoftwareDetailId] = [t0].[Id]
) AS [Count]
FROM [SoftwareDetails] AS [t0]
有谁知道让 EF 在计数中使用特定列而不是所有列?
【问题讨论】:
标签: c# sql linq linq-to-entities left-join