3

動的SQLWHERE句を生成するために、標準のビジターパターンを使用してLINQ式ツリーを反復処理しています。

私の問題は、C#とは異なり、SQLでスタンドアロンのブール式を使用できないことです。1または0と比較する必要があります。

この架空のラムダ式を考えると:

h => h.Enabled || h.Enabled == false

このコードを誤って生成するのは簡単です。

WHERE Enabled OR Enabled = 0

またはこのコード:

WHERE (Enabled = 1) OR (Enabled = 1) = 0

もちろん、どちらもSQLエラーを生成します。サブツリーを深く掘り下げてケースがどうなるかを理解するときに、コードが本当に鈍く見え始めることなく、これを回避するためにどのロジックを適用する必要がありますか?

編集:上記の例はもちろん冗長です-私はポイントを説明するためにそれを使用しているだけです。

このシナリオを作成できる例:

h => h.Enabled
h => h.Enabled == enabled
h => h.Enabled == true

当然、その最後の例は貧弱なスタイルですが、私のコードはプログラマーのスキルレベルとは無関係に機能するように設計されているため、冗長なシナリオに対応しないことは私の側では貧弱な形式になります。

4

3 に答える 3

5

次のケースは非常に簡単です。

h => h.Enabled == enabled
h => h.Enabled == true

これらはBinaryExpressionノードであり、次のように直接変換できます。

WHERE (Enabled = @p0)
WHERE (Enabled = 1)

処理する必要がある特別なケースは次のとおりです。

h => h.Enabled
h => !h.Enabled

これらは、式ツリーで ( としてMemberExpression) 異なる方法で表されます。そのため、特殊なケースを作成しMemberExpression、ブール値のプロパティにアクセスしているかどうかを判断する必要があります。そうである場合は、それを正規の形式に変換します ( UnaryExpression2 番目の例で を検出します)。

WHERE (Enabled = 1)
WHERE (Enabled = 0)

または、式ツリーを前処理して、特殊なケースを標準 (式ツリー) 形式に変換できる場合もあります。たとえばMemberExpression、基準に適合するすべてのノードを正しい に変換できますBinaryExpression

于 2009-11-23T09:12:04.063 に答える
0

演算子を評価する前にオペランドを完全に処理することはできませんか?

すなわち。以下のそれぞれを評価します。

h => h.Enabled
h => h.Enabled == enabled
h => h.Enabled == true

WHERE (Enabled = 1)

次に、演算子がラムダに含まれている場合は、レンダリングされたオペランドのコレクションを同等の SQL で処理して、演算子の要件を満たします。

于 2009-11-23T09:08:44.857 に答える