1

さて、2 つのデータ行のキーと値のペアの違いを取得する必要があります。簡単に言えば、ユーザーが自分のプロファイルに特定の変更を加えたことを知らせるためにメールを送信しています。を使用してそれを判断しているため、行が異なることは既にわかっています。SequenceEqual

現時点では、次のコードを作成してデバッグしました。

if (currentRow.ItemArray.SequenceEqual(updatedRow)) { return; }
var updates = currentRow.ItemArray
    .Where((o, i) =>
    {
        if (o == null && updatedRow[i] == null) { return false; }
        else if (o == null && updatedRow[i] != null) { return true; }
        else if (o.Equals(updatedRow[i])) { return false; }
        return true;
    })
    .Select((o, i) =>
    {
        return new AppServices.NotificationData
        {
            Key = updatedRow.Table.Columns[i].ColumnName,
            Value = Convert.ToString(updatedRow[i])
        };
    }).ToList();

しかし、このコードには 2 つの問題があります。

  1. の各値を調べて、値が異なる場合はItemArrayキーと値のペアを作成するため、私には非常に非効率的です。
  2. iに送信されたSelectが正しくないため、実際には機能しません1(たとえば、2 番目の列が変更された場合、 に送信されたインデックスSelectは実際に0はここに欲しい。

制約:ここで LINQ を使用したいと思います。

注:私は 2 つの行のみを比較しています (つまり、行のリストを通過するつもりはありません)。

ここでやろうとしていることに対する適切な LINQ ステートメントは何ですか?

更新:本当に使用する必要があるように感じます:

currentRow.ItemArray.Intersect(updatedRow.ItemArray)

しかし、それに関する問題は、それがどのフィールドなのかわからないため、キーと値のペアを作成できないことです。つまり、違いのみを取得しますが、インデックスが何であるかがわからないため、それらの値に基づいて列名を取得することはできません。

4

3 に答える 3

1

一般に、LINQ で配列インデックス値を使用することは「コードのにおい」であると考えています。これはその理由の良い例です。Where 句は、値の新しいシーケンスを生成する際に、Select 句が機能しているという幻想を破壊します。前回と同じコレクション。

今すぐこれを回避するための簡単なハック (ただし、まだ適切な解決策ではないと思います) は、基本的に Where 句と Select 句を交換することです。

if (currentRow.ItemArray.SequenceEqual(updatedRow)) { return; }
var updates = currentRow.ItemArray
    .Select((o, i) =>
    {
        if (o == null && updatedRow[i] == null || o.Equals(updatedRow[i])) { return null; }
        else return new AppServices.NotificationData
        {
            Key = updatedRow.Table.Columns[i].ColumnName,
            Value = Convert.ToString(updatedRow[i])
        };
    }).Where(o => o != null).ToList();
于 2013-09-09T13:40:50.950 に答える