2013-03-06 3 views
1

J'ai une requête:LINQ: jointure gauche au lieu de jointure

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) 
         }); 

Cette requête se traduit par T-SQL comme ceci:

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] 

-je remplacer INNER JOIN avec LEFT JOIN . Ni plus ni moins. J'ai essayé quelques variantes avec .DefaultIfEmpty(), mais cela ne fonctionne pas comme je le veux. Voici mes: Essais

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) 
        }); 

se transforme en:

 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] 

et celui-ci

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) 
         }); 

se transforme en

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] 

Je ne sais pas comment faire il. Besoin d'aide, les gars!

+1

Que diriez-vous reformater vos fenêtres de code pour être lisible dans les fenêtres? –

+0

Quelles propriétés de navigation avez-vous dans 'CrossGroup'? Vous ne devriez probablement pas vous joindre du tout. –

+0

Je n'ai pas de propriétés de navigation utiles dans 'CrossGroup'. L'inscription est vraiment nécessaire. – Nenormalniy

Répondre

0

Voici un moyen de tricher. Si vous voulez juste remplacer la jointure interne par la jointure gauche. Pas très recommandé dans un environnement de production. Il ne fonctionne bien =)

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(); 

;-)

Questions connexes