2

私は、LINQ 式 (基本的には LINQ-to-SQL の変更されたサブセット) から SQL を生成するライブラリに取り組んでいます。私は判別共用体を使用して SQL 式をモデル化していますが、いくつかの (認識されている?) 制限に遭遇しました。次のようなことをしたい(最後の行に注意してください):

type SqlSourceExpression =
    | Table of string
    | Join of JoinType * SqlSourceExpression * SqlSourceExpression * SqlExpression //ie, left, right, predicate

and SqlExpression =
    | Source of SqlSourceExpression
    | OrderBy of SqlExpression * SortDirection
    | Select of SqlSourceExpression * SqlExpression * OrderBy list //can't do this

私は次のことができます:

type SqlOrderByExpression = SqlExpression * SortDirection

...最後の 2 行を次のように変更します。

    | OrderBy of SqlOrderByExpression
    | Select of SqlSourceExpression * SqlExpression * SqlOrderByExpression list

しかし、これには次の 2 つの問題があるようです。

  1. SqlOrderByExpression は SqlExpression ではありません。これにより、ビジター パターンの使用が難しくなります (ここに問題があるのではないでしょうか?)。つまり、Select 式をトラバースするときに、各式を Visit(expr:SqlExpression) に渡す order by 式のリストを反復処理することはできません。

  2. SqlOrderByExpression は単なるタプルの型エイリアスであるため、型情報は保持されません。それは読みやすさIMOを傷つけます。

これをモデル化するより良い方法はありますか?継承ルートを試してみましたが、DU の方が作業がはるかに簡単だと思います (前述の難しさを除けば)。

4

2 に答える 2

1

FP テクニック (DU) を使用する場合、OOP パターンを覚える必要がないため、高次関数 (折り畳み、マップ、ジッパーなど) を使用するだけです。

一致するコードの特定のビューだけが必要な場合は、アクティブなパターンがあります。

let (|OrderByTerm|OrderByList|_|)= function
  |OrderBy x -> Some (OrderByTerm x)
  |Select (_,_,xs) -> Some (OrderByList xs)
  |_ -> None
于 2009-12-09T18:04:34.367 に答える
0

SqlExpression差別された組合として、なぜ と のケースがあるのOrderByか​​ わかりませんSelect。の中に何を入れることができOrderByますか?

差別された労働組合がこれを必要以上に難しくしていると思います。SqlSourceExpressionSqlOrderByExpressionSqlSelectExpressionは異なるタイプであると思います。タプルが読みにくいことが心配な場合は、それらをレコードにすることができます (これは私があなたの状況で行うことです)。

構文がより柔軟な のSqlExpressionような式ツリーを表現し始めると、判別共用体が役立つと思います。(1 + SUM(ISNULL(Value1, Value2))) / COUNT(*)

于 2009-12-09T17:52:51.387 に答える