2013-03-06 27 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(); 

;-)