【发布时间】:2021-06-25 14:02:36
【问题描述】:
我已经自定义了查询类,它将用于在 lambda 表达式的帮助下构建查询,如下所示
var query = new Query("Person").Where<Person>(p =>
(p.Name == "Maulik" && (p.Id == 2 || p.Age == 30)) || (p.Id == 2 && p.Name == "Maulik"));
通过基于此参考link 类实现ExpressionVisitor,我能够将翻译后的查询转换为字符串格式,如下所示
(((Name EqualTo "Maulik") AND ((Id EqualTo 2) OR (Age EqualTo 30))) OR ((Id EqualTo 2) AND (Name EqualTo 'Maulik')))
但是,我想将上面的表达式翻译成我的自定义嵌套类
public class Expression
{
public List<Expression> Filters { get; } // Nested expression
public Operator Operator { get; set; } //e.g AND/OR
public List<Condition> Conditions { get; } // One Expression can have many conditions
}
public class Condition
{
public string Name { get; set; }
public Operator Operator { get; set; } //e.g <,> ==, != etc
public object Value { get; set; }
}
表达式表示:(A > 5 && A < 10),条件表示最内部的条件A > 5
我的意思是嵌套,一个表达式可以有子表达式,也可以有子子表达式等等,每个表达式可以有多个条件。
转换成这种结构的原因是为了处理各种 SQL/NoSQL 提供者,从这种类结构中将为所有不同的提供者创建单独的查询,因此不能完全改变这种类结构。
创建这个类结构是为了维护基于查询的AND和OR条件的括号顺序,因此相同级别的条件可以用单个表达式来俱乐部。
我正在寻找任何可以帮助将表达式转换为嵌套类结构的通用映射。
将表达式转换为自定义嵌套类结构的最佳方法是什么?如果有任何可用的实施示例,请分享。我还没有找到任何相关的例子。
【问题讨论】:
-
如果您使用像实体框架这样的 ORM,甚至只是使用 Linq to SQL,那么这一切都会为您处理。真的有必要重新发明这个轮子吗?它可以完成,但是嵌套和子相关表达式和投影的复杂数组意味着要正确执行此操作,您将重新创建 EF 的 Db 提供程序,或者一旦 Linq 不是最基本的标准,就会出现运行时错误
-
是的需要这样做,因为需要支持各种Sql/NoSql提供者,所以这个中间类层将用于翻译成DB特定查询
-
@Maulik 这些数据库都没有现有的 LINQ 提供程序?
-
@Servy 不是所有的,但包括 NoSql 在内的少数没有 LINQ 提供程序
-
@Maulik 那你为什么要为所有这些编写查询提供程序?为每个支持它的数据库使用现有的提供程序。
标签: c# lambda expression func expressionvisitor