web-dev-qa-db-ja.com

LINQとC#を使用してリストで要素を更新する方法

オブジェクトのリストがあり、いずれかのオブジェクト内の特定のメンバー変数を更新したいのですが。 LINQはクエリ用に設計されており、不変データのリストを更新するためのものではないことを理解しています。これを達成するための最良の方法は何でしょうか?それが最も効率的でない場合、ソリューションにLINQを使用する必要はありません。

Update拡張メソッドの作成は機能しますか?もしそうなら、私はそれをどうやってやりますか?

EXAMPLE:
(from trade in CrudeBalancedList
 where trade.Date.Month == monthIndex
 select trade).Update(
 trade => trade.Buy += optionQty);
13
Addie

Linqは不変データのリストを更新するためのものではありませんが、更新するアイテムを取得するのに非常に便利です。私はあなたにとってこれは次のようになると思います:

(from trade in CrudeBalancedList
    where trade.Date.Month == monthIndex
    select trade).ToList().ForEach( trade => trade.Buy += optionQty);
30
Patrick Karcher

これが最善の方法かどうかはわかりませんが、リストから要素を更新できます。

テストオブジェクト:

 public class SomeClass {
        public int Value { get; set; }
        public DateTime Date { get; set; }
    }

拡張メソッド:

public static class Extension {
        public static void Update<T>(this T item, Action<T> updateAction) {
            updateAction(item);
        }
    }

テスト:

public void Test()
{
    // test data
    List<SomeClass> list = new List<SomeClass>()
    {
        new SomeClass {Value = 1, Date = DateTime.Now.AddDays(-1)},
        new SomeClass {Value = 2, Date = DateTime.Now },
        new SomeClass {Value = 3, Date = DateTime.Now.AddDays(1)}
    };
    // query and update
    (from i in list where i.Date.Day.Equals(DateTime.Now.Day) select i).First().Update(v => v.Value += 5);

    foreach (SomeClass s in list) {
        Console.WriteLine(s.Value);
    }
}
4
Fernando

したがって、ここでは単一の結果が得られることを期待しています。その場合は、SingleOrDefaultメソッドの利用を検討してください。

var record =
    (from trade in CrudeBalancedList
    where trade.Date.Month == monthIndex
    select trade).SingleOrDefault();

if (record != null)
    record.Buy += optionQty;

SingleOrDefaultメソッドは正確に1またはの値が返されることを期待していることに注意してください(一意の主キーのテーブル内の行のように)。複数のレコードが返された場合、メソッドは例外をスローします。

1
Dan Tao

このようなメソッドを作成するには、そのプロトタイプから始めます。

public static class UpdateEx {
    public void Update(this IEnumerable<T> items, 
                       Expression<Action> updateAction) {
    }
}

それは簡単な部分です。

難しいのは、Expression<Action>をSQL更新ステートメントにコンパイルすることです。サポートする構文の量に応じて、このようなコンパイラーの複雑さは、取るに足らないものから不可能までさまざまです。

Linq式のコンパイル例については、 sqlite-netプロジェクトTableQueryクラスを参照してください。

0
Frank Krueger