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