admin管理员组文章数量:1439716
dotnet 10 LINQ LeftJoin & RightJoin
dotnet 10 LINQ LeftJoin & RightJoin
Intro
.NET 10 Preview 1 为 LINQ 支持了 LeftJoin
和 RightJoin
,此前我们只支持 Join
,需要自己实现,在 .NET 10 中将内置 LeftJoin
/RightJoin
并且 EF 也将为之提供支持
New API
新增 API 如下:
代码语言:javascript代码运行次数:0运行复制namespace System.Linq;
publicstaticclassEnumerable
{
publicstatic IEnumerable<TResult> LeftJoin<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner?, TResult> resultSelector);
publicstatic IEnumerable<TResult> LeftJoin<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner?, TResult> resultSelector,
IEqualityComparer<TKey>? comparer);
publicstatic IEnumerable<TResult> RightJoin<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter?, TInner, TResult> resultSelector);
publicstatic IEnumerable<TResult> RightJoin<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter?, TInner, TResult> resultSelector,
IEqualityComparer<TKey>? comparer);
}
publicstaticclassQueryable
{
publicstatic IQueryable<TResult> LeftJoin<TOuter, TInner, TKey, TResult>(
this IQueryable<TOuter> outer,
IEnumerable<TInner> inner,
Expression<Func<TOuter, TKey>> outerKeySelector,
Expression<Func<TInner, TKey>> innerKeySelector,
Expression<Func<TOuter, TInner?, TResult>> resultSelector);
publicstatic IQueryable<TResult> LeftJoin<TOuter, TInner, TKey, TResult>(
this IQueryable<TOuter> outer,
IEnumerable<TInner> inner,
Expression<Func<TOuter, TKey>> outerKeySelector,
Expression<Func<TInner, TKey>> innerKeySelector,
Expression<Func<TOuter, TInner?, TResult>> resultSelector,
IEqualityComparer<TKey>? comparer);
publicstatic IQueryable<TResult> RightJoin<TOuter, TInner, TKey, TResult>(
this IQueryable<TOuter> outer,
IEnumerable<TInner> inner,
Expression<Func<TOuter, TKey>> outerKeySelector,
Expression<Func<TInner, TKey>> innerKeySelector,
Expression<Func<TOuter?, TInner, TResult>> resultSelector);
publicstatic IQueryable<TResult> RightJoin<TOuter, TInner, TKey, TResult>(
this IQueryable<TOuter> outer,
IEnumerable<TInner> inner,
Expression<Func<TOuter, TKey>> outerKeySelector,
Expression<Func<TInner, TKey>> innerKeySelector,
Expression<Func<TOuter?, TInner, TResult>> resultSelector,
IEqualityComparer<TKey>? comparer);
}
Sample
使用起来和 Join
类似,只是 LeftJoin
/RightJoin
的时候可能会 map 不到数据导致有数据可能会 null,使用起来也是非常的简单,下面是一个简单的使用示例:
var jobs = new[]
{
new
{
Id = 1,
Name = "test"
}
};
var employeeList = new[]
{
new
{
Id = 1,
JobId = 1,
Name = "Alice"
},
new
{
Id = 2,
JobId = 2,
Name = "Jane"
}
};
var result = employeeList.LeftJoin(jobs, e => e.JobId, j => j.Id, (e, j) => new
{
e.Id,
e.Name,
e.JobId,
JobName = j?.Name ?? "Unnamed"
});
foreach (var item in result)
{
Console.WriteLine(JsonSerializer.Serialize(item));
}
这里两个员工对应两个 job 但是 job collection 里只有一个 job,会导致 left join 的时候,job 可能会为 null
,我们设置了 JobName 在 Job 为 null 时显示为 Unnamed
,执行结果如下:
left-join output
类似地我们也可以使用 right join
代码语言:javascript代码运行次数:0运行复制foreach (var item in jobs.RightJoin(employeeList, j => j.Id, e => e.JobId, (j, e) => new
{
e.Id,
e.Name,
e.JobId,
JobName = j?.Name ?? "Unknown"
}))
{
Console.WriteLine(JsonSerializer.Serialize(item));
}
输出结果如下:
代码语言:javascript代码运行次数:0运行复制{"Id":1,"Name":"Alice","JobId":1,"JobName":"test"}
{"Id":2,"Name":"Jane","JobId":2,"JobName":"Unknown"}
More
如果要在已有的项目里使用,可以在自己的项目里实现一个扩展方法,实现代码如下:
代码语言:javascript代码运行次数:0运行复制public static IEnumerable<TResult> LeftJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner?, TResult> resultSelector)
{
return outer
.GroupJoin(inner, outerKeySelector, innerKeySelector,
(outerObj, inners) => new { outerObj, inners = inners.DefaultIfEmpty() })
.SelectMany(a => a.inners.Select(innerObj => resultSelector(a.outerObj, innerObj)));
}
References
- .linq.enumerable.join
- .cs
本文标签: dotnet 10 LINQ LeftJoin ampamp RightJoin
版权声明:本文标题:dotnet 10 LINQ LeftJoin &amp; RightJoin 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/biancheng/1747631132a2733041.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论