从具有匹配ID的两个列表创建树的方法
本文关键字:两个 列表 创建 方法 ID | 更新日期: 2023-09-27 17:52:38
假设我有以下两个模型:
public class Order
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public string Street { get; set; }
public IList<Appointment> Appointments { get; set; }
}
public class Appointment
{
public Guid Id {get; set;}
public DateTime StartDate {get; set;}
public DateTime EndDate {get; set;}
public Guid OrderId { get; set; }
}
我有一个包含Order项的列表(所有的appointment列表都为空)和一个包含所有约会的列表,我不知道如何匹配这两个列表中的元素,以便获得包含所有相应约会的Order对象(基于OrderId)。
我怎样才能有效地做到这一点?我不想遍历所有订单,并分配相应的约会。
首先,通过OrderId
创建Appointment
的字典:
var appointmentByOrderId = appointments
.GroupBy(a => a.OrderId)
.ToDictionary(g => g.Key, g => g.ToList());
然后遍历Order
s的列表,并将Appointments
设置为字典中的列表:
foreach (var order in orders) {
List<Appointment> appointmentList;
if (appointmentByOrderId.TryGetValue(order.Id, out appointmentList) {
order.Appointments = appointmentList;
} else {
order.Appointments = new List<Appointment>();
}
}
else
分支是可选的。如果您不希望将空列表设置为具有空约会列表的订单,则可以删除该列表。
一种方法是将两个列表"group join"并投影一个新的集合:
var neworders =
from o in orders
join a in appointments
on o.Id equals a.OrderId
into g
select new Order
{
Id = o.Id,
Name = o.Name,
Location = o.Location,
Street = o.Street,
Appointments = g.ToList()
};
显然,这会创建新的 Order
对象-如果不希望这样做,另一种选择是循环遍历所有订单并"附加"匹配的约会-使用ToLookup
对它们进行预分组:
var groups = appointments.ToLookup(a => a.OrderId);
foreach(var o in orders)
o.Appointments = groups[o.Id].ToList();
构建一个Dictionary<Guid, Order>
,并用您的所有订单填充它。然后浏览约会列表,并按适当的顺序添加。例如(假设您有一个名为Orders
的列表和一个名为Appointments
的列表):
var OrdersDictionary = Orders.ToDictionary(o => o.Id, o => o);
foreach (var appt in Appointments)
{
OrdersDictionary[appt.OrderId].Appointments.Add(appt);
}
可能有一种LINQ方法可以在单个语句中完成所有的rollup,但是我没有花时间来解它。