GroupJoin
我使用标准的//方法编写了一个在 LINQ 中执行左连接的方法SelectMany
:DefaultIfEmpty
public static IQueryable<TResult> LeftJoin<TLeft, TRight, TKey, TResult>(
this IQueryable<TLeft> left,
IEnumerable<TRight> right,
Expression<Func<TLeft, TKey>> leftKeySelector,
Expression<Func<TRight, TKey>> rightKeySelector,
Expression<Func<TLeft, TRight, TResult>> resultSelector)
{
var paramL = Expression.Parameter(typeof(TLeft), "l");
var paramR = Expression.Parameter(typeof(TRight), "r");
var paramRs = Expression.Parameter(typeof(IEnumerable<TRight>), "rs");
var expr = Expression.Lambda<Func<TLeft, IEnumerable<TRight>, IEnumerable<TResult>>>(
Expression.Call(
typeof(Enumerable),
"Select",
new [] { typeof(TRight), typeof(TResult) },
Expression.Call(typeof(Enumerable), "DefaultIfEmpty", new[] { typeof(TRight) }, paramRs),
Expression.Lambda<Func<TRight, TResult>>(
Expression.Invoke(resultSelector, paramL, paramR),
paramR)),
paramL,
paramRs
);
return left
.GroupJoin(
right,
leftKeySelector,
rightKeySelector,
expr)
.SelectMany(x => x);
}
我因此对其进行了测试:
var q = myDB.PurchaseOrderHeaders
.LeftJoin(
myDB.PurchaseOrderLines,
po => po.PurchaseOrderGUID,
line => line.PurchaseOrderGUID,
(po, line) => new { PO = po, Line = line }
);
var e = q.AsEnumerable();
我期望 SQL 是这样的:
SELECT [t0].[PurchaseOrderGUID], ..., [t1].[PurchaseOrderLineGUID], ...
FROM [dbo].[PurchaseOrderHeader] AS [t0]
LEFT OUTER JOIN [dbo].[PurchaseOrderLine] AS [t1]
ON [t0].[PurchaseOrderGUID] = [t1].[PurchaseOrderGUID]
但是得到了这个:
SELECT [t0].[PurchaseOrderGUID], ..., [t2].[test], [t2].[PurchaseOrderLineGUID], ...
FROM [dbo].[PurchaseOrderHeader] AS [t0]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t1].[PurchaseOrderLineGUID], ...
FROM [dbo].[PurchaseOrderLine] AS [t1]
) AS [t2] ON [t0].[PurchaseOrderGUID] = [t2].[PurchaseOrderGUID]
不同之处在于带有 的子查询SELECT 1 as [test]
。为什么会产生这个?它可能对性能产生任何重大影响吗?如果是这样,我可以修改查询以消除它吗?