私は、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 つの問題があるようです。
SqlOrderByExpression は SqlExpression ではありません。これにより、ビジター パターンの使用が難しくなります (ここに問題があるのではないでしょうか?)。つまり、Select 式をトラバースするときに、各式を Visit(expr:SqlExpression) に渡す order by 式のリストを反復処理することはできません。
SqlOrderByExpression は単なるタプルの型エイリアスであるため、型情報は保持されません。それは読みやすさIMOを傷つけます。
これをモデル化するより良い方法はありますか?継承ルートを試してみましたが、DU の方が作業がはるかに簡単だと思います (前述の難しさを除けば)。