2014-09-22 47 views
1

我正在使用System.Linq.Dynamic能夠編寫動態查詢,但我無法弄清楚如何將列表(IEnumerable)參數傳遞給查詢: 這裏是我想實現:System.Linq.Dynamic:使用列表(IEnumerable)參數

SELECT * FROM People WHERE Role IN ('Employee','Manager') 

而這裏的LINQ的相當於同一查詢:

from person in People where (new string[]{"Employee","Manager"}).Contains(person.Role) 

所以我對自己說,我可以使用動態的LINQ作爲編寫這個查詢:

People.Where("@0.Contains(Role)","(new string[]{\"Employee\",\"Manager\"})") 

這個版本是不工作也不:

People.Where("(new string[]{"Employee","Manager"}).Contains(Role)") 

所以這裏的問題:如何申請動態的LINQ庫能夠與列表或IEnumerable的參數工作,如出現上述情況?

回答

1

動態LINQ默認不支持Contains

你可以做到這一點在老辦法:

var roles = new[] { "Employee", "Manager" }; 
var predicate = new StringBuilder(); 
for (var i = 0; i < roles.Length; i++) 
{ 
    string role = roles[i]; 
    predicate.AppendFormat("Role = @{0}", i); 
    if (i < roles.Length) predicate.Append(" OR "); 
} 

People.Where(predicate.ToString(), role.Cast<object>().ToArray()); 

這裏是關於這個問題:link。在提到的問題中還有其他替代品。

+0

那麼我正在尋找一個更方便的方法。 – Beatles1692 2014-09-22 08:36:32

+0

@ Beatles1692所以,​​你也可以在'DynamicLinq.cs'中編輯'predefinedTypes',就像我提供的問題的回答中所提到的那樣; – 2014-09-22 08:37:51

+1

我認爲這也是一個有點可疑的解決方案,除非我可以提供項目的推送請求。 – Beatles1692 2014-09-22 08:44:12

2

Dynamic linq項目本身不支持'contains',我有相同的要求,必須下載源代碼並修改它以支持它。

我失去了跟上任何nuget更新的能力,但該解決方案現在可以滿足我們的需求。我無法找到我發現的位置,但這是我做到的。

編輯的Dynamic.cs文件,並添加以下行周圍566:

interface IEnumerableSignatures 
{ 
    bool Contains(object selector); // Add this 
    void Where(bool predicate); 
    //... 
// Then around line 628 add a new keyword: 

static readonly string keywordOuterIt = "outerIt"; 
static readonly string keywordIt = "It"; 
//... 
// above ParameterExpression It; add 
ParameterExpression outerIt; 

// In ParseIdentifier add 
if (value == (object)keywordOuterIt) return ParseOuterIt(); 

//Then add that method 
Expression ParseOuterIt() 
{ 
    if (outerIt == null) 
     throw ParseError(Res.NoItInScope); 
    NextToken(); 
    return outerIt; 
} 

// In ParseAggreggate, add: 
outerIt = it; 

if (signature.Name == "Min" || signature.Name == "Max") 
{ 
    typeArgs = new Type[] { elementType, args[0].Type }; 
} 
else 
{ 
    typeArgs = new Type[] { elementType }; 
} 
if (args.Length == 0) 
{ 
    args = new Expression[] { instance }; 
} 
else 
{ 
    // add this section 
    if (signature.Name == "Contains") 
     args = new Expression[] { instance, args[0] }; 
    else 
    { 
     args = new Expression[] { instance, Expression.Lambda(args[0], innerIt) }; 
    } 
} 

// In CreateKeyWords() 

d.Add(keywordOuterIt, keywordOuterIt); // Add this 

我不知道,如果我們可以在這裏上傳源,但我一直保持我自己的動態副本。 CS,並試圖保持它與nuget上的版本保持同步。如果你願意,我會很樂意上傳它。我只是不記得我在哪裏得到了所有這些,因爲在動態LINQ上搜索包含大部分產生錯誤結果 - 指向字符串包含,而不是IEnumerable.contains。

+1

你可以在這裏獲得源代碼:https://github.com/kahanu/System.Linq.Dynamic/blob/master/Src/System.Linq.Dynamic/DynamicLinq.cs – reckface 2014-09-22 09:58:32

+1

我認爲最新的nuget包現在已經解決了這個問題。我查看了最新的來源,並且發生了這些變化。 – reckface 2014-12-18 18:00:10