2015-04-07 53 views
2

我使用帶代碼優先和遷移的EF。我有兩個實體:在linq中指定具有左外部聯接的計數列

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使用計數中的特定列而不是所有列?

回答

0

非題主義問題:不應該將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() }; 
+0

不幸的是,這並不能產生期望的SQL。這也是一個'內部連接'。 – valdetero

+0

你怎麼樣告訴我確切的SQL語句,我幫你翻譯成LINQ查詢 –

+0

我做到了。我說生成的SQL,然後我想要替換。 – valdetero