两个list集合得到linq外连接的效果

9 篇文章 0 订阅

两个list集合得到linq外连接的效果

  网络

像这种怎么写?



你写的语句仅仅是左外连接,而你要的结果却是左外连接和右外连接的交集(以user_id为键做比较)。

当然通常我们不会这样做,因为太低效。

一个简单点的办法是先取两个list的user_id做并集运算得到所有的主键,然后依据主键进行子查询。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var  tmp1 =      list1
                 .Select(i => i.user_id)
                 .Union(list2.Select(i => i.user_id))
                 .ToList()
                 .Select(id =>
                     {
                         var  i1 = list1.FirstOrDefault(i => i.user_id == id);
                         var  i2 = list2.FirstOrDefault(i => i.user_id == id);
                         return  new
                         {
                             user_id = i1 ==  null  ? i2.user_id : i1.user_id,
                             num1 = i1 ==  null  ? 0 : i1.num1,
                             pic = i1 ==  null  ? 0 : i1.pic,
                             num2 = i2 ==  null  ? 0 : i2.num2,
                             send = i2 ==  null  ? 0 : i2.send
                         };
                     });

稍微解释下。首先我们拿到list1和list2的所有user_id,然后使用Union扩展方法做并集运算得到匿名IEnumerable<int>,里面的值是{1,2,3,4,5}。对其中每一个值id,在list1和list2上比较user_id==id得到i1和i2。根据i1和i2是否为空决定该如何select结果集。


等价的查询子句语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var  tmp11 =  from  id  in
                 ( from  i1  in  list1  select  i1.user_id)
                     .Union(( from  i2  in  list2  select  i2.user_id))
                     .ToList()
             let  r1 = ( from  i1  in  list1  where  i1.user_id == id  select  i1)
                     .FirstOrDefault()
             let  r2 = ( from  i2  in  list2  where  i2.user_id == id  select  i2)
                     .FirstOrDefault()
             select  new
                    {
                        user_id = r1 ==  null  ? r2.user_id : r1.user_id,
                        num1 = r1 ==  null  ? 0 : r1.num1,
                        pic = r1 ==  null  ? 0 : r1.pic,
                        num2 = r2 ==  null  ? 0 : r2.num2,
                        send = r2 ==  null  ? 0 : r2.send
                    };

 

如果想利用现有的代码,我们还可以为newList补上它缺失的记录。检查一下list2中所有user_id没有在list1中出现的记录即可。

1
2
3
4
5
6
7
8
9
10
11
newList = newList.Concat(
               from  in  list2
               where  !( from  in  list1  select  a.user_id).Contains(b.user_id)
               select  new
               {
                   user_id = b.user_id,
                   num1 = 0,
                   pic = 0,
                   num2 = b.num2,
                   send = b.send
               });

等价的查询符语法:

1
2
3
4
5
6
7
8
9
10
11
newList = newList.Concat(
               list2
               .Where(i2 => !list1.Select(i1 => i1.user_id).Contains(i2.user_id))
               .Select(b =>  new
                         {
                             user_id = b.user_id,
                             num1 = 0,
                             pic = 0,
                             num2 = b.num2,
                             send = b.send
                         }));

还有其他几种方式可以满足你的需要,这里就不过多解释了。有问题请追问。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值