私はシステムを実装することを考えています。それは、 'ビルド'条件を使用して、結果のデータをデータベースから返すことです。現在、オンザフライでSQLを生成して実行するストアドプロシージャがあります。これは私が削除したい特定の問題です。複数の/未知の基準を持つ動的linqクエリ
私の条件は、私の基準内に複数のフィールドを持つことができるという事実から来ています。これらの各フィールドには、異なる可能性のある演算子を持つ1つ以上の値があります。例えば、
from t in Contacts
where t.Email == "[email protected]" || t.Email.Contains ("mydomain")
where t.Field1 == "valuewewant"
where t.Field2 != "valuewedontwant"
select t
フィールド、基準オペレータは
をデータベースに格納されている(そしてList<FieldCriteria>
)および(上記に基づいて)このようないくつかのものになるだろうしています。
Email, Equals, "[email protected]"
Email, Contains, "mydomain" Field1,
Equals, "valuewewant" Field2,
DoesNotEqual, "valuewedontwant"
または
new FieldCriteria
{
FieldName = "Email",
Operator = 1,
Value = "[email protected]"
}
だから私は持っている情報を使用して、私は条件の任意の数のクエリを作成できるようにしたいです。私はDynamic LinqとPredicateBuilderへの以前のリンクを見てきましたが、これを私自身の問題の解決策として視覚化することはできません。
何か提案がありがとうございます。
ダイナミックにLINQについての提案に続いて更新
、私は2つのフィールドと複数の条件で、シングル演算子を使用して、非常に基本的な解決策を考え出しました。現時点でLinqPadでコード化されているような少し原油ですが、結果はまさに私が望んでいたものです。
enum Operator
{
Equals = 1,
}
class Condition
{
public string Field { get; set; }
public Operator Operator { get; set;}
public string Value { get; set;}
}
void Main()
{
var conditions = new List<Condition>();
conditions.Add(new Condition {
Field = "Email",
Operator = Operator.Equals,
Value = "[email protected]"
});
conditions.Add(new Condition {
Field = "Email",
Operator = Operator.Equals,
Value = "[email protected]"
});
conditions.Add(new Condition {
Field = "Field1",
Operator = Operator.Equals,
Value = "Chris"
});
var statusConditions = "Status = 1";
var emailConditions = from c in conditions where c.Field == "Email" select c;
var field1Conditions = from c in conditions where c.Field == "Field1" select c;
var emailConditionsFormatted = from c in emailConditions select string.Format("Email=\"{0}\"", c.Value);
var field1ConditionsFormatted = from c in field1Conditions select string.Format("Field1=\"{0}\"", c.Value);
string[] conditionsArray = emailConditionsFormatted.ToArray();
var emailConditionsJoined = string.Join("||", conditionsArray);
Console.WriteLine(String.Format("Formatted Condition For Email: {0}",emailConditionsJoined));
conditionsArray = field1ConditionsFormatted.ToArray();
var field1ConditionsJoined = string.Join("||", conditionsArray);
Console.WriteLine(String.Format("Formatted Condition For Field1: {0}",field1ConditionsJoined));
IQueryable results = ContactView.Where(statusConditions);
if (emailConditions != null)
{
results = results.Where(emailConditionsJoined);
}
if (field1Conditions != null)
{
results = results.Where(field1ConditionsJoined);
}
results = results.Select("id");
foreach (int id in results)
{
Console.WriteLine(id.ToString());
}
}
SQLを生成した場合。
-- Region Parameters
DECLARE @p0 VarChar(1000) = 'Chris'
DECLARE @p1 VarChar(1000) = '[email protected]'
DECLARE @p2 VarChar(1000) = '[email protected]'
DECLARE @p3 Int = 1
-- EndRegion
SELECT [t0].[id]
FROM [Contacts].[ContactView] AS [t0]
WHERE ([t0].[field1] = @p0) AND (([t0].[email] = @p1) OR ([t0].[email] = @p2)) AND ([t0].[status] = @p3)
とコンソール出力:
Formatted Condition For Email: Email="[email protected]"||Email="[email protected]"
Formatted Condition For Field1: Field1="Chris"
はこれをクリーンアップし、他の演算子を追加必要とそれが格好良いです。
誰もがこれまでのところ、この上の任意のコメントを持っている場合は、任意の入力は、私は、動的LINQは選択肢の一つになると思い
「LINQ to」の考え方は、静的なC#コンパイル時の式を、実行のために基になるデータベースに送信する何らかの種類の文字列に変換することです。文字列をlinq式に変換して文字列に変換することをお勧めします:) –
"静的"な表現はSQLに対して正しいですが、ユーザーが知りませんコンパイル時の式についてのことです。したがって、実行時に式を生成する必要があります。 DLINQは "文字列"からそれを行う1つの方法ですが、他の方法はExpression APIを使用して実行時に必要な式を作成することです。 – Ankur