0

我想要一个用户(通常是高级用户)可以输入布尔表达式的应用程序。我希望能够在 .NET 和 SQL 中执行布尔表达式。

表达式本身并不难,它们是这样的:

  • 国家是美国
  • 国家是以下国家之一:美国、加拿大、墨西哥
  • (国家是美国)和(年龄是 20 岁)
  • (国家为美国)或((年龄为 20 岁)且国家为以下国家之一:美国、加拿大)

我需要能够支持基本的东西,如'in'、等于、大于/小于、介于、包含、startswith 等。我希望能够编译成 C# 并针对 type 的对象运行它dynamic,并且也是能够将表达式编译成 SQL。我会将结果插入到非常具体的查询的 where 子句中。

我不想使用 Nhibernate 或 EntityFramework,我希望能够直接执行 SQL。

更新: 我已经知道我想使用 ADO.NET 执行它。对不起,如果我没有说清楚。我只是想知道存储一个可以在 C# 和 SQL 中执行的布尔表达式的好方法是什么。我不关心存储过程和参数化(一旦我能够生成查询,后者是显而易见且微不足道的)。输入表达式的用户是我公司内部的,主要是开发人员和高级用户。

所以我正在考虑使用表达式树、抽象语法树、LINQ 等来实现这一点。我不想使用 ORM,但我想做一些与 ORM 在其 LINQ 表达式中所做的非常相似的事情,以将 lambas 转换为WHERE子句的代码。

UPDATE2: 到目前为止,我们正在考虑这样做的方式是将表达式作为 C# 输入并作为字符串存储在数据库中。当我们想在 .NET 上下文中执行时,我们会编译成 lambda 或 Expression 并可能将其包装在一个对象中,该对象作为一个接口与一个方法来表示布尔表达式interface IDynamicFilter { bool PassesFilter<SomePocoType>(poco); }。或者我们可以将 POCO(s) 放入 IEnumerable 并运行 LINQ .Where() 并传入 lambda/表达式,以提取与过滤器匹配的对象。

对于 SQL,这是我比较模糊的部分。我们想要复制 ORM 的功能——访问一个表达式树并将其呈现为一个 SQL 字符串。我们不需要支持全套 SQL。我们只需要支持非常简单的运算符,例如带括号的分组、AND/OR/NOT、in/not in、GT/LT/EQ/NEQ/between。我们还希望支持一些基本的数学运算 ( a + b > c)。

4

2 回答 2

0

如果我了解您的问题,您可以执行以下操作(请记住,我不建议将此类事情用于生产):

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,这种逻辑应该在你传递参数的存储过程中。

于 2013-03-08T02:15:34.550 回答
0

Microsoft CRM 有类似的东西,它们为您提供表单字段和一个下拉列表,指定您要查找的内容以及您的逻辑运算符是什么,因此您可能拥有。

Column:
Select Column in Database

Opeartor: 
>
<
>=
<=
LIKE
=
IN
NOT IN

Value:
TextBox for user input

因此,您将获取用户输入并基于此创建查询。如果您不想使用像实体这样的 ORM,那么您可以使用 ADO.NET。

于 2013-03-08T01:45:42.507 回答