0

ユーザー (通常はパワー ユーザー) がブール式を入力できるアプリが必要です。.NET と SQL の両方でブール式を実行できるようにしたいと考えています。

式自体はそれほど難しいものではなく、次のようなものです。

  • 国はアメリカ合衆国です
  • 国は次のいずれかです: 米国、カナダ、メキシコ
  • (国は米国) AND (年齢は 20 歳)
  • (country is United States) OR ((age is 20) and country is one of: United States, canada)

「in」、equals、greater/less than、between、contains、startswith などの基本的なものをサポートできる必要があります。C# にコンパイルして、type のオブジェクトに対して実行できるようにしたいと考えていますdynamic。式を SQL にコンパイルできます。結果を非常に具体的なクエリの where 句に挿入します。

Nhibernate や EntityFramework を使用したくありません。SQL を直接実行できるようにしたいのです。

更新: ADO.NET を使用して実行したいことは既にわかっています。はっきり言わなかったらごめんなさい。C# と SQL の両方で実行できるブール式を格納するための適切な方法を知りたいだけです。ストアド プロシージャとパラメーター化は気にしません (クエリを生成できるようになれば、後者は明白で些細なことです)。式を入力するユーザーは社内のユーザーで、ほとんどが開発者とパワー ユーザーです。

だから私はこれを達成するために、式ツリー、抽象構文ツリー、LINQ などを使用する方向に沿って考えています。私は ORM を使用したくありませんが、ORM が LINQ 式でラムバをWHERE句のコードに変換するのと非常によく似た処理を実行したいと考えています。

更新 2: これまでに考えている方法は、式を C# として入力し、データベースに文字列として格納することです。.NET コンテキストで実行する場合は、ラムダまたは式にコンパイルし、ブール式を表すメソッドとのインターフェイスとしてオブジェクトにラップしますinterface IDynamicFilter { bool PassesFilter<SomePocoType>(poco); }。または、POCO を IEnumerable にドロップし、渡されたラムダ/式で LINQ .Where() を実行して、フィルターに一致するオブジェクトを引き出すことができます。

SQL の場合、これは私がより曖昧にしている部分です。ORM が行うことを複製したいと考えています。つまり、Expression ツリーにアクセスして、それを 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 に答える