![](/img/trans.png)
[英]How to copy properties from one list to another using Linq conditionally
[英]How to change values of few properties from one list to another using 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 list OrderId value from order list when CustomerName is matching with Name prop
替换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;
las,如果您有多个Orders
的Customer
,这将不起作用:
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应该具有OrderId 77还是78?
您确定每个客户只有一个订单吗?
要获得Customer with all his Orders
的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所说,我将对直接处理数据保持谨慎。
您可以遍历成对的客户和对应的订单,并仅针对匹配的对更新客户。
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
循环将清楚地告诉其他开发人员您的意图。
您需要将customer的属性Name
和order的属性CustomerName
都加入列表,然后从Order分配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}, \t Name: {item.Name}, \t OrderId: {item.OrderId}");
}
Console.ReadLine();
输出:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.