如何修改LINQ投影中的一个或两个字段

本文关键字:一个 字段 两个 何修改 修改 LINQ 投影 | 更新日期: 2023-09-27 18:03:42

我有这个LINQ查询:

List<Customers> customers = customerManager.GetCustomers();
return customers.Select(i => new Customer {
    FullName = i.FullName,
    Birthday = i.Birthday, 
    Score = i.Score,
    // Here, I've got more fields to fill
    IsVip = DetermineVip(i.Score)
}).ToList();

换句话说,在我的业务方法中,我只希望根据条件修改客户列表中的一个或两个字段。我有两种方法,

  1. 使用for...each循环,遍历客户并修改该字段(命令式方法)
  2. 使用LINQ投影(声明式方法)

是否有任何技术在LINQ查询中使用,只修改投影中的一个属性?例如:

return customers.Select(i => new Customer {
    result = i // telling LINQ to fill other properties as it is
    IsVip = DetermineVip(i.Score) // then modifying this one property
}).ToList();

如何修改LINQ投影中的一个或两个字段

可以使用

return customers.Select(i => {
    i.IsVip = DetermineVip(i.Score);
    return i;
}).ToList();

与其他答案相反,您可以通过调用Select语句中的方法来修改linq中的源内容(注意EF不支持这一点,尽管这对您来说应该不是问题)。

return customers.Select(customer => 
{
    customer.FullName = "foo";
    return customer;
});

如果创建一个复制构造函数,用现有对象的值初始化一个新对象,那么

partial class Customer
{
    public Customer(Customer original)
    {
        this.FullName = original.FullName;
        //...
    }
}

那么你可以这样做:

return customers.Select(i => new Customer(i) { IsVip = DetermineVip(i.Score)})
    .ToList()

但是这里的缺点是您将基于每个现有对象创建一个新的Customer对象,而不是修改现有对象-这就是为什么我把"can"放在引号中。我不知道这是不是你想要的。

不,Linq被设计为迭代集合而不影响源可枚举对象的内容。

但是,您可以创建自己的方法来迭代和改变集合:

public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
    foreach(T item in enumeration)
    {
        action(item);
    }
}

你可以这样使用:

return customers.ToList()
                .ForEach(i => i.IsVip = DetermineVip(i.Score))
                .ToList();

注意,第一个ForEach将克隆源列表。

由于customers已经是一个List,您可以使用ForEach方法:

customers.ForEach(c => c.IsVip = DetermineVip(c.Score));