如何在LINQ中正确执行LEFT JOIN
本文关键字:执行 LEFT JOIN LINQ | 更新日期: 2023-09-27 17:58:00
这是我的查询。我想在LINQ 中这样做
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),
});
您的查询可能看起来像
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,
});
}
我认为您只缺少一个DefaultIfEmpty()。"?"在r.tm?中?。ConfigValue??。。。捕获"r.tm"的NullPointer
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));