我正在开发一个从 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
...并将最后两行更改为:
| OrderBy of SqlOrderByExpression
| Select of SqlSourceExpression * SqlExpression * SqlOrderByExpression list
但这似乎有两个问题:
SqlOrderByExpression 不是 SqlExpression。这使得很难使用访问者模式(也许这就是问题所在?)。这意味着在遍历 Select 表达式时,我无法通过将每个表达式传递给 Visit(expr:SqlExpression) 的表达式来迭代顺序列表。
SqlOrderByExpression 仅仅是一个元组的类型别名,所以没有类型信息被保留。这会损害 IMO 的可读性。
有没有更好的方法来建模这个?我尝试了继承路线,但我认为 DU 更容易使用(除非有提到的困难)。