我如何设置一个布尔表达式,可以在c#和SQL中执行,而不依赖于像EntityFramework这样的库
本文关键字:执行 SQL 依赖于 EntityFramework 设置 何设置 一个 布尔表达式 | 更新日期: 2023-09-27 18:03:06
我想有一个应用程序,其中用户(通常是一个高级用户)可以输入布尔表达式。我希望能够在。net和SQL中执行布尔表达式。
表达式本身并不难,它们是这样的:
- 国家为美国
- 国家为:美国、加拿大、墨西哥
- (国家为美国)和(年龄为20岁)
- (国家为美国)或(年龄为20岁),国家为:美国,加拿大)
我需要能够支持基本的东西,如"in",等于,大于/小于,之间,包含,开始与等。我希望能够编译成c#,并运行它对类型的dynamic
的对象,也能够编译表达式成SQL。我将把结果插入到一个非常特定查询的where子句中。
我不想使用Nhibernate或EntityFramework,我想能够直接执行SQL。
更新:我已经知道我想用ADO.NET来执行它。抱歉我没有说清楚。我只是想知道一个好的方法是存储一个布尔表达式,可以在c#和SQL中执行。我不关心存储过程和参数化(一旦我能够生成查询,后者就显得很明显和微不足道了)。输入表达式的用户是我公司内部的,主要是开发人员和高级用户。
所以我正在考虑使用像表达式树,抽象语法树,LINQ等东西来完成这一点。我不想使用ORM,但我想做一些非常类似于ORM在LINQ表达式中所做的事情,将lambas转换为WHERE
子句的代码。
更新2:到目前为止,我们考虑的方法是将表达式作为c#输入,并将其作为字符串存储在数据库中。当我们想要在。net上下文中执行时,我们会编译成lambda或Expression,并可能将其包装在一个对象中,该对象作为接口与表示布尔表达式interface IDynamicFilter { bool PassesFilter<SomePocoType>(poco); }
的方法。或者我们可以将POCO放入IEnumerable中,并使用传入的lambda/表达式运行LINQ . where(),以提取与过滤器匹配的对象。
对于SQL,这是我比较模糊的部分。我们希望复制ORM所做的事情——访问表达式树并将其呈现为SQL字符串。我们不需要支持全套SQL。我们只需要支持非常简单的操作符,比如用括号分组,AND/OR/NOT, in/NOT in, GT/LT/EQ/NEQ/between。我们还想支持一些基本的数学运算(a + b > c
)。
Microsoft CRM有类似的东西,它们为您提供表单字段和指定您要查找的内容以及您的逻辑运算符的下拉菜单,因此您可能有。
Column:
Select Column in Database
Opeartor:
>
<
>=
<=
LIKE
=
IN
NOT IN
Value:
TextBox for user input
你会获取用户输入并基于它创建查询。如果你不想使用像Entity这样的ORM,那么你可以使用ADO.NET。
如果我理解你的问题,你可以这样做(请记住,我不推荐这种事情用于生产):
var query = "SELECT * FROM TABLE as T WHERE 1=1";
if ([some condition]) query += " AND T.CountryCode = 'USA'";
if ([some other condition]) query += " AND T.CountryCode IN ('USA', 'CAN', 'MEX')";
if ([yet another condition]) query += " AND T.CountryCode = 'USA' AND T.Age = 20";
using (var conn = new SqlConnection(connectionString))
{
conn.Open();
using (var comm = new SqlCommand(conn, query))
{
var results = comm.ExecuteReader(); //returns an IDataReader you can loop through.
}
}
我再说一遍,确保你是参数化你正在搜索的任何变量,这种类型的查询很容易受到sql注入。这是懒惰的开发人员做事的方式,而且可能相当危险。如果您想要避免ORM,这种类型的逻辑应该在您传递参数的存储过程中。