LINQ full join left outer join union IEquatable

本文演示了如何使用LINQ进行左外联接、右外联接,并通过Union操作合并结果。通过具体实例展示了使用自定义类及匿名类进行联接的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linq方法实现起来比较麻烦,这里用linq语句来实现

指定对象join和union

这里选择最麻烦的List<Object>

直接贴代码

class Program
    {
        public static void Main(string[] args)
        {
            List<User> users = new List<User>
            {
                new User{
                    ID=1,
                    UserName="小张",
                    Age=19,
                },
                new User { 
                    ID = 2, 
                    UserName = "小王", 
                    Age = 25,
                },
            };
            List<Dog> dogs = new List<Dog>
            {
                new Dog
                {
                    UserId=null,
                    DogName="小野狗",
                },
                new Dog
                {
                    UserId=2,
                    DogName="二哈"
                }
            };
            //左outer join
            List<Result> left = (from a in users
                        join b in dogs on a.ID equals b.UserId into c
                        from d in c.DefaultIfEmpty()
                        select new Result
                        {
                            ID = a.ID,
                            UserName = a.UserName,
                            Age = a.Age,
                            UserId = d?.UserId ?? 0,
                            DogName = d?.DogName ?? ""
                        }).ToList();
            //右outer join
            List<Result> right = (from a in dogs
                         join b in users on a.UserId equals b.ID into c
                         from d in c.DefaultIfEmpty()
                         select new Result
                         {
                             ID = d?.ID ?? 0,
                             UserName = d?.UserName ?? "",
                             Age = d?.Age ?? 0,
                             UserId = a.UserId,
                             DogName = a.DogName,
                         }).ToList();
            //注意Result需要自己规定去重方式,否则Union无法去重
            var result = left.Union(right);
            foreach (var item in result)
            {
                Console.WriteLine($"ID:{item.ID} UserName:{item.UserName} Age:{item.Age} UserId:{item.UserId} DogName:{item.DogName}");
            }
            Console.ReadLine();
        }
    }

    class User
    {
        public int ID { get; set; }
        public string UserName { get; set; }
        public int Age { get; set; }
    }

    class Dog
    {
        public int? UserId { get; set; }
        public string DogName { get; set; }
    }
    //IEquatable<Result> 否则Union无法去重
    class Result : IEquatable<Result>
    {
        public int ID { get; set; }
        public string UserName { get; set; }
        public int Age { get; set; }
        public int? UserId { get; set; }
        public string DogName { get; set; }
        //自定义比较方式
        public bool Equals(Result other)
        {
            return ID == other.ID && UserName.Equals(other.UserName) && DogName.Equals(other.DogName);
        }
        public override int GetHashCode()
        {
            return ID.GetHashCode();
        }
    }

如果是自己新建类来接受结果,那么类要实现IEquatable<T>,这样Union在去重的时候会调用类的Equals方法来去重。

匿名对象join和union

有时候我们使用C#中的匿名类,先来看看匿名类的比较

匿名类字段名称、顺序、类型注意要一致,否则不是同一种匿名类!静态类型,属性只读。

class Program
    {
        static void Main(string[] args)
        {
            DateTime today = DateTime.Now;
            var Obj1 = new
            {
                ID = 1,
                Name = "test",
                TestDate = today
            };
            var Obj2 = new
            {
                ID=1,
                Name="test",
                TestDate = today
            };
            Console.WriteLine(Obj1 == Obj2);
            //false 所以Obj1!=Obj2
            Console.WriteLine(Obj1.Equals(Obj2));
            //true  所以Obj1  euqals  Obj2    
            Console.ReadLine();
        }
    }

可以看到匿名类如果字段值一样,Equals方法的比较结果是true。

所以我们这里可以把第一部分的对象全部使用匿名类来试一下

直接贴代码

var users = new[]
            {
                new {
                    ID=1,
                    UserName="小张",
                    Age=19,
                },
                new  {
                    ID = 2,
                    UserName = "小王",
                    Age = 25,
                },
            };
            var dogs = new[]
            {
                new {
                    UserId=3,
                    DogName="小野狗",
                },
                new {
                    UserId=2,
                    DogName="二哈"
                }
            };
            //左outer join
            var left = (from a in users
                                 join b in dogs on a.ID equals b.UserId into c
                                 from d in c.DefaultIfEmpty()
                                 select new 
                                 {
                                     ID = a.ID,
                                     UserName = a.UserName,
                                     Age = a.Age,
                                     UserId = d?.UserId ?? 0,
                                     DogName = d?.DogName ?? ""
                                 }).ToList();
            //右outer join
            var right = (from a in dogs
                                  join b in users on a.UserId equals b.ID into c
                                  from d in c.DefaultIfEmpty()
                                  select new 
                                  {
                                      ID = d?.ID ?? 0,
                                      UserName = d?.UserName ?? "",
                                      Age = d?.Age ?? 0,
                                      UserId = a.UserId,
                                      DogName = a.DogName,
                                  }).ToList();
            //匿名类不需要实现equals可以直接去重
            var result = left.Union(right);
            foreach (var item in result)
            {
                Console.WriteLine($"ID:{item.ID} UserName:{item.UserName} Age:{item.Age} UserId:{item.UserId} DogName:{item.DogName}");
            }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值