4

PredicateBuilder を使用して動的 Where 句を作成し、DataTable からデータをクエリします。検索する必要がある列名と値を含む Dictionary があります。キーが列名と一致する場合は、辞書を反復処理しているだけで、そのキーと値を述語に追加します。実際のクエリがデータテーブルに対して実行されるまで、すべてが正常に機能しているように見えますが、レコードが返されません:(しかし、動的述語を p => p["Year"] == "2010" のようなものに置き換えると、レコードが取得されますコードは次のとおりです。

var objectList = table.AsEnumerable();
Func<DataRow, bool> predicate = GetPredicate(parms, table.Columns);

var list1 = objectList.Where(predicate).ToList();

private static Func<DataRow, bool> GetPredicate(Dictionary <string, string> parms, DataColumnCollection dataColumnCollection)
    {
        var predicate = PredicateBuilder.False<DataRow>();
        foreach (var parm in parms)
        {
            if (dataColumnCollection.Contains(parm.Key))
            {
                var copy = parm;
                predicate = predicate.And(p => p[copy.Key] == copy.Value);
            }
        }
        return predicate.Compile();
    }

どんな助けでも大歓迎です:)

4

1 に答える 1

8

句から始めてfalse、句を追加していますand

false && ...常に を返すfalseため、Where句は何にも一致しません。

次から始めてみてください。

var predicate = PredicateBuilder.True<DataRow>();

また:

ループ変数を閉じています。これは、すべての述語が最後のparminを使用することを意味しますparms

これは、ループ内にローカル コピーを作成することで修正できます。

foreach( var parm in parms )
{
  if (dataColumnCollection.Contains(parm.Key))
  {
    var copy = parm;
    predicate = predicate.And( p => p[ copy.Key ] == copy.Value );
  }

アップデート:

DataRow[ key ]は 型objectであるため、p[ copy.Key ] == copy.Valueでは、等値演算子は文字列の等値ではなく、オブジェクト参照の等値です。

これを修正するには、次を指定しString.Equalsます。

predicate = predicate.And( p => String.Equals( p[ copy.Key ], copy.Value ) );

string興味深いことに、この例は、同じ内容ののインスタンスを複数持つことができることを示しています。

于 2013-01-14T16:45:25.060 に答える