不多说了,看代码
看到别人的,记录下来,
Zip() – 简单一对一的联接
该方法针对两个不同类执行一个最简单的联接。比如给定两个序列,它仅仅将他们的第一个项合并,而后将他们第二个项合并,…,一旦到达较短序列的最后一项,它就会立即停止。
比方说,比如,我们有下面的类定义:
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public double Salary { get; set; }
}
public class Seat
{
public int Id { get; set; }
public double Cost { get; set; }
}
然后,我们确定了以下顺序:
var employees = new List<Employee>
{
new Employee { Id = 13, Name = "John Doe", Salary = 13482.50 },
new Employee { Id = 42, Name = "Sue Smith", Salary = 98234.13 },
new Employee { Id = 99, Name = "Jane Doe", Salary = 32421.12 }
};
var seats = new List<Seat>
{
new Seat { Id = 1, Cost = 42 },
new Seat { Id = 2, Cost = 42 },
new Seat { Id = 3, Cost = 100 },
new Seat { Id = 4, Cost = 100 },
new Seat { Id = 5, Cost = 125 },
new Seat { Id = 6, Cost = 125 },
};
我们可以联接它们,给每个雇员提供一个座位:
var seatingAssignments = employees.Zip(seats, (e, s) => new
{ EmployeeId = e.Id, SeatId = s.Id });
foreach (var seat in seatingAssignments)
{
Console.WriteLine("雇员: " + seat.EmployeeId + " 预约了座位 " + seat.SeatId);
}
我们可以得到:
雇员: 13 预约了座位1
雇员: 42 预约了座位2
雇员: 99 预约了座位3
Join() – 满足条件的联接
“使用 join 子句可以将来自不同源序列并且在对象模型中没有直接关系的元素相关联。唯一的要求是每个源中的元素需要共享某个可以进行比较以判断是否相等的值。 例如,食品经销商可能具有某种产品的供应商列表以及买主列表。 例如,可以使用 join 子句创建该产品同一指定地区供应商和买主的列表。
join 子句接受两个源序列作为输入。 每个序列中的元素都必须是可以与另一个序列中的相应属性进行比较的属性,或者包含一个这样的属性。 join 子句使用特殊的 equals 关键字比较指定的键是否相等。 join 子句执行的所有联接都是同等联接。 join 子句的输出形式取决于所执行的联接的具体类型。 ”
是否相等取决于IEqualityComparer<T>,如果你使用自定义的类型,你需要提供 Equals() 和 GetHashCode() 或者提供一个自定义的 IEqualityComparer<T>. 但是你使用的.NET 中的类型,则一般不需要再另外实现这些函数。
上例子,使用之前的Employee类,再加一个Badge类,然后我们再创建这一组序列:
public class Badge
{
public int EmployeeId { get; set; }
public int BadgeNumber { get; set; }
}
var employees = new List<Employee>
{
new Employee { Id = 13, Name = "John Doe", Salary = 13482.50 },
new Employee { Id = 42, Name = "Sue Smith", Salary = 98234.13 },
new Employee { Id = 99, Name = "Jane Doe", Salary = 32421.12 }
};
var badges = new List<Badge>
{
new Badge { EmployeeId = 10, BadgeNumber = 1 },
new Badge { EmployeeId = 13, BadgeNumber = 2 },
new Badge { EmployeeId = 20, BadgeNumber = 3 },
new Badge { EmployeeId = 25, BadgeNumber = 4 },
new Badge { EmployeeId = 42, BadgeNumber = 5 },
new Badge { EmployeeId = 10, BadgeNumber = 6 },
new Badge { EmployeeId = 13, BadgeNumber = 7 },
};
这样我们就可以使用Join 来对它们进行操作了:
var badgeAssignments = employees.Join(badges, e => e.Id, b => b.EmployeeId,
(e, b) => new { e.Name, b.BadgeNumber });
foreach (var badge in badgeAssignments)
{
Console.WriteLine("Name: " + badge.Name + " has badge " + badge.BadgeNumber);
}
返回的结果是:
Name: John Doe has badge 2
Name: John Doe has badge 7
Name: Sue Smith has badge 5
Join 对于1:1的关系是非常实用的,或者如果你不在乎返回一些重复的1:N的关系,你也可以是用Join.
GroupJoin() – 适用于一对多的条件联接
那么,如果你有1:N的关系,你希望这些结果分类组合在一起就可以用到 GroupJoin(),仍旧用上面的例子:
var badgeAssignments = employees.GroupJoin(badges, e => e.Id, b => b.EmployeeId,
(e, bList) => new { Name = e.Name, Badges = bList.ToList() });
foreach (var assignment in badgeAssignments)
{
Console.WriteLine(assignment.Name + " has badges:");
if (assignment.Badges.Count > 0)
{
foreach (var badge in assignment.Badges)
{
Console.WriteLine("/tBadge: " + badge.BadgeNumber);
}
}
else
{
Console.WriteLine("/tNo badges.");
}
}
结果如下:
John Doe has badges:
Badge: 2
Badge: 7
Sue Smith has badges:
Badge: 5
Jane Doe has badges:
No badges.
如果你想进步一强化对Join 和 GroupJoin 区别的了解,可以再一次看看上面两个例子输入的结果。