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 つまたは 2 つのフィールドのみを変更したいと考えています。これを行うには2つの方法があります。

  1. for...eachループを使用して顧客をループし、そのフィールドを変更します (必須のアプローチ)
  2. LINQ プロジェクションの使用 (宣言型アプローチ)

プロジェクションで1つのプロパティのみを変更するために、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オブジェクトを作成することです。これが、「缶」を引用符で囲んだ理由です。これが本当にあなたが望むものであるかどうかはわかりません。

于 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

customers はすでに List であるため、ForEach メソッドを使用できます。

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