6

我有这个 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();
4

5 回答 5

5

您可以使用

return customers.Select(i => {
    i.IsVip = DetermineVip(i.Score);
    return i;
}).ToList();
于 2013-03-13T06:19:34.810 回答
2

你“可以”,如果你创建一个复制构造函数,它用现有对象的值初始化一个新对象:

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”放在引号中的原因。我不知道这是否真的是你想要的。

于 2013-03-13T06:17:34.277 回答
2

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

return customers.Select(customer => 
{
    customer.FullName = "foo";
    return customer;
});
于 2013-03-13T06:30:00.917 回答
1

不,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 将克隆源列表。

于 2013-03-13T06:16:05.797 回答
0

由于客户已经是一个列表,您可以使用 ForEach 方法:

customers.ForEach(c => c.IsVip = DetermineVip(c.Score));
于 2013-03-13T06:27:46.080 回答