2013-03-06 29 views
1

我有一個查詢:LINQ:左連接,而不是內部聯接

var groups = query 
       .Where(x => x.CrossSearchArticle == searchParameters.SearchString) 
       .Join(RuntimeValues.Context.SiteBrands, 
         cross => cross.CrossBrandID, 
         brand => brand.SiteBrandsID, 
         (cross, brand) => new { cross, brand }) 
       .GroupBy(x => x.cross.CrossGroupID) 
       .Select(x => new ProductClarify 
         { 
          CrossGroupID = x.Key, 
          CrossGroupName = x.Max(z => z.cross.CrossGroupName), 
          SourceArticle = x.Max(z => z.cross.SourceArticle), 
          SiteBrandName = x.Max(z => z.brand.Name) 
         }); 

這個查詢轉換成T-SQL這樣的:

SELECT 
    1 AS [C1], 
    [GroupBy1].[K1] AS [CrossGroupID], 
    [GroupBy1].[A1] AS [C2], 
    [GroupBy1].[A2] AS [C3], 
    [GroupBy1].[A3] AS [C4] 
    FROM (SELECT 
     [Extent1].[CrossGroupID] AS [K1], 
     MAX([Extent1].[CrossGroupName]) AS [A1], 
     MAX([Extent1].[SourceArticle]) AS [A2], 
     MAX([Extent2].[Name]) AS [A3] 
     FROM [dbo].[ArticlesCrosses] AS [Extent1] 
     INNER JOIN [dbo].[SiteBrands] AS [Extent2] 
      ON [Extent1].[CrossBrandID] = [Extent2].[SiteBrandsID] 
     WHERE [Extent1].[CrossSearchArticle] = @p__linq__0 
     GROUP BY [Extent1].[CrossGroupID] 
    ) AS [GroupBy1] 

我需要更換INNER與LEFT JOIN JOIN 。沒有更多,不少。 我使用.DefaultIfEmpty()嘗試了一些變體,但它不能按我想要的方式工作。 這裏是我的期試驗研究:

var groups = query 
       .Where(x => x.CrossSearchArticle == searchParameters.SearchString) 
       .Join(RuntimeValues.Context.SiteBrands.DefaultIfEmpty(), 
         cross => cross.CrossBrandID, 
         brand => brand.SiteBrandsID, 
         (cross, brand) => new { cross, brand }) 
       .GroupBy(x => x.cross.CrossGroupID) 
       .Select(x => new ProductClarify 
        { 
         CrossGroupID = x.Key, 
         CrossGroupName = x.Max(z => z.cross.CrossGroupName), 
         SourceArticle = x.Max(z => z.cross.SourceArticle), 
         SiteBrandName = x.Max(z => z.brand.Name) 
        }); 

轉換成:

 SELECT 
     1 AS [C1], 
     [GroupBy1].[K1] AS [CrossGroupID], 
     [GroupBy1].[A1] AS [C2], 
     [GroupBy1].[A2] AS [C3], 
     [GroupBy1].[A3] AS [C4] 
     FROM (SELECT 
      [Extent1].[CrossGroupID] AS [K1], 
      MAX([Extent1].[CrossGroupName]) AS [A1], 
      MAX([Extent1].[SourceArticle]) AS [A2], 
      MAX([Join1].[Name]) AS [A3] 
      FROM [dbo].[ArticlesCrosses] AS [Extent1] 
      INNER JOIN (SELECT [Extent2].[SiteBrandsID] AS [SiteBrandsID], 
           [Extent2].[Name] AS [Name] 
       FROM (SELECT 1 AS X) AS [SingleRowTable1] 
       LEFT OUTER JOIN [dbo].[SiteBrands] AS [Extent2] ON 1 = 1) AS [Join1] 
    ON ([Extent1].[CrossBrandID] = [Join1].[SiteBrandsID]) 
     OR (([Extent1].[CrossBrandID] IS NULL) AND ([Join1].[SiteBrandsID] IS NULL)) 
      WHERE [Extent1].[CrossSearchArticle] = @p__linq__0 
      GROUP BY [Extent1].[CrossGroupID] 
     ) AS [GroupBy1] 

而這一次

var groups = query 
       .Where(x => x.CrossSearchArticle == searchParameters.SearchString) 
        .Join(RuntimeValues.Context.SiteBrands, 
          cross => cross.CrossBrandID, 
          brand => brand.SiteBrandsID, 
          (cross, brand) => new { cross, brand }) 
        .DefaultIfEmpty() 
        .GroupBy(x => x.cross.CrossGroupID) 
      .Select(x => new ProductClarify 
         { 
          CrossGroupID = x.Key, 
          CrossGroupName = x.Max(z => z.cross.CrossGroupName), 
          SourceArticle = x.Max(z => z.cross.SourceArticle), 
          SiteBrandName = x.Max(z => z.brand.Name) 
         }); 

轉換成

SELECT 
    1 AS [C1], 
    [GroupBy1].[K1] AS [CrossGroupID], 
    [GroupBy1].[A1] AS [C2], 
    [GroupBy1].[A2] AS [C3], 
    [GroupBy1].[A3] AS [C4] 
    FROM (SELECT 
     [Project1].[CrossGroupID] AS [K1], 
     MAX([Project1].[CrossGroupName]) AS [A1], 
     MAX([Project1].[SourceArticle]) AS [A2], 
     MAX([Project1].[Name]) AS [A3] 
     FROM (SELECT 1 AS X) AS [SingleRowTable1] 
     LEFT OUTER JOIN (SELECT 
      [Extent1].[CrossGroupID] AS [CrossGroupID], 
      [Extent1].[CrossGroupName] AS [CrossGroupName], 
      [Extent1].[SourceArticle] AS [SourceArticle], 
      [Extent2].[Name] AS [Name] 
      FROM [dbo].[ArticlesCrosses] AS [Extent1] 
      INNER JOIN [dbo].[SiteBrands] AS [Extent2] 
         ON [Extent1].[CrossBrandID] = [Extent2].[SiteBrandsID] 
      WHERE [Extent1].[CrossSearchArticle] = @p__linq__0) AS [Project1] 
        ON 1 = 1 
     GROUP BY [Project1].[CrossGroupID] 
    ) AS [GroupBy1] 

我不知道該怎麼辦它。需要幫助,夥計們!

+1

如何重新格式化您的代碼窗口是在窗口可讀? – 2013-03-06 08:20:38

+0

你在CrossGroup中有什麼導航屬性?你根本不應該加入。 – 2013-03-06 08:52:22

+0

我在'CrossGroup'中沒有有用的導航屬性。加盟是非常必要的。 – Nenormalniy 2013-03-06 09:55:54

回答

0

這是一種欺騙的方法。如果你真的只想用左連接替換內連接。在生產環境中不太可取。它雖然=工作)

DataContext ctx = yourcontext; 
var x = from a in atable 
    join b in btableon a.key equals b.key 
    select a; //returns atype 
string sql = ctx.GetCommand(x).CommandText; 
var y = ctx.ExecuteQuery(typeof(atype),sql.Replace("INNER JOIN","LEFT JOIN")); 
y.Dump(); 

;-)