概要: PredicateBuilderを使用してOr()
いくつかの式をまとめてから、その組み合わせた式をOrmLiteのSelect()
メソッドに送信しています。ただし、生成された SQL には、WHERE
SQL Server がエラーをスローする、入れ子になった括弧が非常に多い句があります。これを回避するにはどうすればよいですか?
詳細:Foo
2 つの列を持つテーブルがBar
ありBaz
ます。Bar/Baz 値のコレクションがあり、一致するすべての行を見つけたい場合は、(たとえば) 次の SQL を発行します。
SELECT * FROM Foo WHERE (Bar=1 AND Baz=1) OR (Bar=2 AND Baz=3) OR ...
私はOrmLiteを使用PredicateBuilder
しているので、where 句を生成するために使用しています。
var predicate = PredicateBuilder.False<Foo>();
foreach (var nextFoo in fooList)
predicate = predicate.Or(foo => nextFoo.Bar == foo.Bar &&
nextFoo.Baz == foo.Baz);
Db.Select(predicate);
リストに 3 つの Foo を指定してこれを実行すると、生成された SQL は次のようになります (簡潔にするためにクリーンアップされていますが、意図的に 1 行に残しています)。
SELECT Bar, Baz FROM Foo WHERE ((((1=0) OR ((1=Bar) AND (1=Baz))) OR ((2=Bar) AND (3=Baz))) OR ((2=Bar) AND (7=Baz)))
先頭の括弧に注意してください。はPredicateBuilder
、次の式を追加する前に既存の式を継続的に括弧で囲んで、x
-> (x) or y
->((x) or y) or z
などとします。
私の問題:検索するアイテムが数十または数百ある場合、生成された SQL には数十または数百のネストされた括弧があり、SQL Server はそれを : でキックバックしますSqlException
。
SQL ステートメントの一部のネストが深すぎます。クエリを書き直すか、小さなクエリに分割します。
それで、これについて何ができますか?ネスト例外を回避したい場合は、生成された SQL のWHERE
句を (上記の例のクエリのように) フラット化する必要があります。独自の SQL を動的に生成して OrmLite のSqlList
メソッドに送信できることはわかっていますが、それを強制されると、OrmLite の価値の半分が失われます。