我期待實現一個系統,通過該系統可以「建立」條件,然後從數據庫中返回結果數據。目前,有一個存儲過程可以即時生成SQL並執行它。這是我想要刪除的特定問題。具有多個/未知條件的動態LINQ查詢
我的問題來自於我可以在我的標準中有多個字段,並且對於這些字段中的每個字段,可能有一個或多個值,以及不同的潛在操作符。
例如,
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]"
}
所以利用我的資料,我希望能夠建立一個查詢任意數量的條件。我已經看到以前的鏈接到動態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 to」的整個想法是將靜態C#編譯時表達式轉換爲某種類型的字符串以發送到底層數據庫以供執行。你建議使用一個字符串轉換爲一個linq表達式,然後轉換爲一個字符串似乎有點多餘:) –
你是正確的關於「靜態」表達式的SQL,但在用戶不知道的問題關於編譯時的表達式,因此您需要在運行時生成表達式。 DLINQ是通過「字符串」實現的一種方式,其他方式是使用Expression API在運行時創建所需的表達式。 – Ankur