如何使用LINQ C#将一些属性的值从一个列表更改为另一个列表:
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用LINQ C#将一些属性的值从一个列表更改为另一个列表:相关的知识,希望对你有一定的参考价值。
我有两个列表
List<Customer> customer = new List<Customer>()
{ Id =1 , Name = 'Demo1' , OrderId = 123}
{ Id =1 , Name = 'Demo2' , OrderId = 123}
List<Order> order = new List<Order>()
{ Id =77 , CustomerName = 'Demo1'}
{ Id =88 , CustomerName = 'Demo2'}
我想取代customer.OrderId = order.Id where order.CustomerName = customer.Name
我想取代customer list OrderId value from order list when CustomerName is matching with Name prop
我正在尝试这样的事情 -
customer = order.Select(eo => new Customer { Name = eo.CustomerName });
这不正确LINQ任何人都可以在这里纠正我吗?
LINQ主要适用于查询,而不适用于数据修改。
相反,我只会使用简单的foreach
:
foreach (var c in customer)
{
var o = order.FirstOrDefault(o => o.CustomerName == c.Name);
c.OrderId = o?.Id ?? 0;
}
当然,当每个客户有多个订单时,这种方法也不会有效。另外我建议将变量重命名为复数 - customers
和orders
以更好地表示它们的含义。
对于纯粹的LINQ方法,您可以编写一个ForEach
LINQ扩展方法,但我发现一个明确的foreach
是一个更易读的解决方案。
LINQ主要用于查询。您可以创建符合要求的新列表。
如果需要,您可以将此新列表分配给变量客户。
您希望以客户名称加入您的客户和订单。
简单方案:
var joinResult = customers.Join(orders, // join the tables of customers with orders
customer => customer.Name, // from every customer take the Name
order => order.CustomerName, // from every order take the CustomerName
(customer, order) => new Customer // when they match make a new Customer
{
Id = customer.Id, // take Id and Name from the matching Customer
Name = customer.Name,
OrderId = order.Id, // take the OrderId from the matching order
})
.ToList();
customers = joinResult;
唉,如果你有几个Customer
的Orders
,这将不起作用:
var customers = new List<Customer>()
{ Id = 1 , Name = 'John Doe' , OrderId = 123},
var orders = new List<Order>()
{ Id =77 , CustomerName = 'John Doe'}
{ Id =88 , CustomerName = 'John Doe'}
客户1是否应该订购订单77或78?
您确定每个客户只有一个订单吗?
要获得Customer with all his Orders
使用GroupJoin
var result = customers.GroupJoin(orders, // GroupJoin the customers with orders
customer => customer.Name, // from every customer take the Name
order => order.CustomerName, // from every order take the CustomerName
(customer, orders) => new // for every customer with all his matching orders
{ // make one new object
Id = customer.Id, // take Id and Name from the matching Customer
Name = customer.Name,
// TODO Decide what to do if there are several orders for customer with this name
// Keep all orders? Or keep the oldest one, the newest one?
// the unpaid ones?
AllOrders = orders.ToList(),
OldestOrder = orders.Orderby(order => order.Date).FirstOrDefault(),
NewestOrder = orders.OrderByDescending(order => order.Date).FirstOrDefault(),
UnpaidOrders = orders.Where(order => order.Status == Status.Unpaid).ToList(),
})
.ToList();
您想要执行连接操作(很可能是内连接)。 LINQ提供了这样的功能
var customerOrders = customer.Join(order,
c => c.Name,
o => o.CustomerName,
(customer, order) =>
{
custumer.OrderId= order.Id;
return customer;
}).ToList();
但正如@Martin Zikmund所说,我要小心直接操纵数据。
您需要从客户和物业Name
订购属性CustomerName
的两个列表,然后从订单中分配OrderId
List<Customer> result = new List<Customer>();
result = (from c in customer
join o in order on c.Name equals o.CustomerName
select new Customer
{
Id = c.Id,
Name = c.Name,
OrderId = o.Id
}).ToList();
foreach (var item in result)
{
Console.WriteLine($"Id: {item.Id}, Name: {item.Name}, OrderId: {item.OrderId}");
}
Console.ReadLine();
输出:
您可以循环访问客户和代理订单对,并仅为匹配对更新客户。
var matched = customers.Join(orders,
customer => customer.Name,
order => order.CustomerName,
(customer, order) => (Customer: customer, Order: order));
foreach (var pair in matched)
{
pair.Customer.OrderId = pair.Order.Id;
}
请注意,如果订单集合包含多个具有相同客户名称的订单,Join
方法将更新客户,并在集合的最后发生订单ID。
LINQ扩展方法以“功能”方式设计,其中枚举项目作为不可变处理。 LINQ方法总是返回集合的新实例。如果在枚举方法中项目会发生变异,大多数开发人员会“非常”感到惊讶。
所以有明确的foreach
循环将清楚地告诉其他开发人员你的意图。
以上是关于如何使用LINQ C#将一些属性的值从一个列表更改为另一个列表:的主要内容,如果未能解决你的问题,请参考以下文章
使用 LINQ 获取两个比较列表的结果并根据结果更改列表中的属性