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

来源:互联网 发布:网络提现 需要牌照 编辑:程序博客网 时间:2024/06/09 23:48

两个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 0
原创粉丝点击