3

こんばんは、

2つのデータテーブル(最後の読み取りと書き込みが必要なデータ)を比較し、変更された行のみを取得する一種のキャッシュを構築しています。DataRowComparer.DefaultをEqualityComparerとして使用していますが、多くのフィールドを持つ行を比較する目的が間違っています。

短いテキスト値を持つ3列のテーブルでは完全に機能しますが、長いテキストの説明を比較すると、1つの文字を変更してもテーブル全体を返すことができません。

コードは非常に単純です。

var diffDs = ds.Tables[0].AsEnumerable().Except(cachedTable.AsEnumerable(), DataRowComparer.Default);

アイデア?ありがとう!

更新: 手動デバッグds.Tables [0] .AsEnumerable()行とcachedtable.AsEnumerable()行を比較できました:DataRowComparerを除いて、完全に同じですが異なります。フォーマットの違いを回避しようとして、DateTime列を削除しましたが成功しませんでした。交差点も機能しません。

更新2: 空/ヌルフィールドでは機能しないことを除いて。IEqualityComparerでは異なるようです。

4

1 に答える 1

0

私は解決策を見つけました:

DataRowComparerコードは次のように機能します。

internal static bool AreEqual(object a, object b)
    {
        if (Object.ReferenceEquals(a, b))
        {   // same reference or (null, null) or (DBNull.Value, DBNull.Value)
            return true;
        }
        if (Object.ReferenceEquals(a, null) || Object.ReferenceEquals(a, DBNull.Value) ||
            Object.ReferenceEquals(b, null) || Object.ReferenceEquals(b, DBNull.Value))
        {   // (null, non-null) or (null, DBNull.Value) or vice versa
            return false;
        }
        return (a.Equals(b) || (a.GetType().IsArray && CompareArray((Array)a, b as Array)));
    }

ご覧のとおり、null値とDBNullは異なる方法で考慮され、null==DBNullは常にfalseです。明らかに、空の文字列はnullフィールドのように見えますが、DBNullではありません。したがって、このnull値のために、明らかに類似している2つのテーブルは異なります。私のソリューションは、xmlソース(これは空の文字列とnull値を持つもの)から構築しながらds.Tables [0]を解析し、S​​ystem.Convert.DBNullで置換を実行します

これで、比較は完全に機能します。

PS\nと\r\ nは、SQLクエリまたはxmlソースからデータテーブルを作成する場合にも異なります。上記のnull/DBNullソリューションを想定して簡単に解決できます。

于 2012-08-09T08:03:30.573 に答える