Left join on two Lists and maintain one property from the right with Linq

前端 未结 4 726
日久生厌
日久生厌 2021-02-06 01:08

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

var leftList = new List();
leftList.Add(new Person {Id = 1, Name = \"John\", Chang         


        
相关标签:
4条回答
  • 2021-02-06 01:27

    Another way to do it would be:

    //Step 1: Merge the lists while selecting the matching objects from rightList using Last()
    var mergedList = leftList.Concat(rightList)
     .GroupBy(x => x.Id)
     .Select(x => x.Last());
    
    //Step 2: Do a inner join between mergedList and leftList to get a left join result as originally required.
    var innerJoinQuery = from mPerson in mergedList
                         join leftPerson in leftList on mPerson.Id equals leftPerson.Id
                         select new { Id = leftPerson.Id, Name = mPerson.Name, Changed = mPerson.Changed };
    
    0 讨论(0)
  • 2021-02-06 01:41

    This looks like a pretty standard left outer join scenario.

    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));
        }
    }
    

    Now you can:

    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})
    
    0 讨论(0)
  • 2021-02-06 01:44

    Well spender was faster then me, I did without any extension method.

    Without any extension method:

    List<Person> mergedList =  leftList
                .GroupJoin(
                    rightList, left => left.Id, right => right.Id, 
                    (x, y) => new { Left = x, Rights = y  }
                )
                .SelectMany(
                    x => x.Rights.DefaultIfEmpty(),
                    (x, y) => new Person
                    {
                        Id = x.Left.Id, 
                        Name = x.Left.Name, 
                        Changed = y == null ? x.Left.Changed : y.Changed
                    }
                ).ToList();
    

    The GroupJoin makes left outer join operation.

    0 讨论(0)
  • 2021-02-06 01:51

    Why don't you try a solution like this:

    var query = (from left in leftList
        join right in rightList on left.Id equals right.Id into joinedList
        from sub in joinedList.DefaultIfEmpty()
        select new Person { 
            Id = left.Id,
            Name = left.Name,
            Changed = sub == null ? left.Changed : sub.Changed }).ToList();
    
    0 讨论(0)
提交回复
热议问题