2016-07-20 20 views
0

這是我的查詢。我想這樣做的LINQ如何正確地在LINQ中進行LEFT JOIN?

SELECT tc.AppId, 
    tc.ConfigCode, 
    tc.ConfigId, 
    tc.ConfigType, 
    COALESCE(tm.ConfigValue, tc.ConfigValue) AS ConfigValue, 
    CASE 
     WHEN tc.ConfigType = 'Application' 
     THEN tc.AppId 
     ELSE tm.Id 
    END as Id, 
FROM dbo.Configs tc 
    LEFT JOIN dbo.ConfigValues tm 
      ON tc.ConfigId = tm.ConfigId 

這裏是我的查詢,我沒有得到正確的結果

db.Configs 
.Join(db.ConfigValues.DefaultIfEmpty(), tc => tc.ConfigId, tm => tm.ConfigId, (tc, tm) => new { tc = tc, tm = tm }) 
.Select(r => new { 
    AppId = (Guid?)r.tc.AppId, 
    ConfigCode = r.tc.ConfigCode, 
    ConfigId = r.tc.ConfigId, 
    ConfigValue = (r.tm.ConfigValue ?? r.tc.ConfigValue), 
    Id = (Guid)(r.tc.ConfigType == "Application" ? r.tc.AppId : r.tm.Id), 
}); 
+0

您是否嘗試過使用具有默認值的「左」側的組連接? –

+0

查看msdn網頁:https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b – jdweng

回答

0

您的查詢可以像

 

db.Configs 
.LeftJoin(db.ConfigValues, tc => tc.ConfigId, tm => tm.ConfigId) 
.Select(r => new {tc = r.Left, tm = r.Right}) 
.Select(r => new { 
    AppId = (Guid?)r.tc.AppId, 
    ConfigCode = r.tc.ConfigCode, 
    ConfigId = r.tc.ConfigId, 
    ConfigValue = (r.tm.ConfigValue ?? r.tc.ConfigValue), 
    Id = (Guid)(r.tc.ConfigType == "Application" ? r.tc.AppId : r.tm.Id), 
}); 
 

如果使用下面的擴展方法。當使用LINQ的流利版本並且可重用時,它會使您的代碼更具可讀性,因爲您可以在其他LINQ查詢中使用LeftJoin/RightJoin。

 

public class LeftJoinResult 
{ 
    public TLeft Left { get; set; } 
    public TRight Right { get; set; } 
} 

public class RightJoinResult 
{ 
    public TRight Right { get; set; } 
    public TLeft Left { get; set; } 
} 

public static IQueryable> LeftJoin(this IQueryable left, IQueryable right, Expression> leftKeySelector, Expression> rightKeySelector) 
    where TRight : class 
{ 
    return left.GroupJoin(right, leftKeySelector, rightKeySelector, (l, r) => new 
    { 
     Left = l, 
     Matches = r.DefaultIfEmpty(), 
    }) 
    .SelectMany(j => j.Matches, (j, m) => new LeftJoinResult 
    { 
     Left = j.Left, 
     Right = m, 
    }); 
} 

public static IQueryable> RightJoin(this IQueryable right, IQueryable left, Expression> rightKeySelector, Expression> leftKeySelector) 
    where TLeft : class 
{ 
    return right.GroupJoin(left, rightKeySelector, leftKeySelector, (r, l) => new 
    { 
     Right = r, 
     Matches = l.DefaultIfEmpty(), 
    }) 
    .SelectMany(j => j.Matches, (j, m) => new RightJoinResult 
    { 
     Right = j.Right, 
     Left = m, 
    }); 
} 
 
0

我認爲你只缺少一個DefaultIfEmpty()。 '?'在r.tm?.ConfigValue ?? ...抓住 'r.tm' 的空指針

db.Configs 
.Join(db.ConfigValues.DefaultIfEmpty(), tc => tc.ConfigId, tm => tm.ConfigId, (tc, tm) => new { tc = tc, tm = tm }) 
.Select(r => new { 
    AppId = (Guid?)r.tc.AppId, 
    ConfigCode = r.tc.ConfigCode, 
    ConfigId = r.tc.ConfigId, 
    ConfigValue = (r.tm.ConfigValue ?? r.tc.ConfigValue), 
    Id = (Guid)(r.tc.ConfigType == "Application" ? r.tc.AppId : r.tm.Id) 
}).DefaultIfEmpty(AppId = (Guid?)r.tc.AppId, 
        ConfigCode = r.tc.ConfigCode, 
        ConfigId = r.tc.ConfigId, 
        ConfigValue = (r.tm?.ConfigValue ?? r.tc.ConfigValue), 
        Id = (Guid)(r.tc.ConfigType == "Application" ? r.tc.AppId : r.tm.Id));