左联接两个列表,并使用Linq从右维护一个属性 [英] Left join on two Lists and maintain one property from the right with Linq

查看:78
本文介绍了左联接两个列表,并使用Linq从右维护一个属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个相同类型的列表.左侧列表:

I have 2 lists of the same type. The left list:

var leftList = new List<Person>();
leftList.Add(new Person {Id = 1, Name = "John", Changed = false});
leftList.Add(new Person {Id = 2, Name = "Alice", Changed = false});
leftList.Add(new Person {Id = 3, Name = "Mike", Changed = false});

以及正确的列表:

var rightList = new List<Person>();
rightList.Add(new Person {Id = 1, Name = "John", Changed = false});
rightList.Add(new Person {Id = 3, Name = "Mike", Changed = true});
rightList.Add(new Person {Id = 4, Name = "Joshi", Changed = true});

我想做一个左联接,但是使用Changed属性上的值.像这样:

I want to do a left join, but using the value on the Changed property from the right. Like this:

{Id = 1, Name = "John", Changed = false}
{Id = 2, Name = "Alice", Changed = false}
{Id = 3, Name = "Mike", Changed = true} // <-- true from the rightList

为此,我不能使用简单的左加入,并且不能使用

For this, I can't use simple Left Join, and I cannot use a Concat with GroupBy.

如何用linq做到这一点?谢谢.

How can I do this with linq? Thanks.

推荐答案

这看起来像是一个非常标准的左外部联接方案.

This looks like a pretty standard left outer join scenario.

对于左外部联接,我总是方便使用此扩展方法,因此不必查看如何使用讨厌的查询语法(或记住wtf是GroupJoin)...

I always keep this extension method handy for left outer joins so I don't have to look up how to use the nasty query syntax (or remember wtf a GroupJoin is)...

public static class LinqEx
{
    public static IEnumerable<TResult> LeftOuterJoin<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, (a, b) => new
            {
                a,
                b
            })
            .SelectMany(x => x.b.DefaultIfEmpty(), (x, b) => resultSelector(x.a, b));
    }
}

现在您可以:

leftList.LeftOuterJoin(
     rightList, 
     lft => lft.Id,
     rgt => rgt.Id,
     (lft, rgt) => new Person{Id = lft.Id, 
                              Name = lft.Name, 
                              Changed = rgt == null ? lft.Changed : rgt.Changed})

这篇关于左联接两个列表,并使用Linq从右维护一个属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆