【问题标题】:Specify count column with left outer join in linq在 linq 中使用左外连接指定计数列
【发布时间】: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


    【解决方案1】:

    题外话:SoftwareDetail不应该是孩子,LicencedSoftware不应该是父母吗,所以forieng键反过来?

    与我的问题无关,请尝试以下方法:

     var query = from softwareDetail in context.SoftwareDetails
                            join licensedSoftware in context.LicensedSoftwares
                                on softwareDetail.Id equals licensedSoftware.SoftwareDetailId
                            select new { softwareDetail, licensedSoftware }
                                into temp
                                group temp by temp.softwareDetail into temp2
                                select new { temp2, count = temp2.Count() };
    

    【讨论】:

    • 不幸的是,这不会生成所需的 sql。这也执行inner join
    • 你告诉我确切的 SQL 语句如何,我帮你翻译成 LINQ 查询
    • 我做到了。我陈述了生成的sql,然后我想要替换。
    • 等我回到电脑前,我会更新帖子。
    • 如果您进行左连接并想知道有多少成功(即非空)左连接结果,那么您进行内连接和计算整个结果集之间有什么区别(这是我的 LINQ 在做什么)?
    猜你喜欢
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    相关资源
    最近更新 更多