2010-05-05 148 views
4

我有一個LINQ to SQL查詢將表從表中返回到IQueryable對象。IQueryable動態「WHERE IN」(LINQ to SQL)

IQueryable<MyClass> items = from table in DBContext.MyTable 
select new MyClass 
{ 
ID = table.ID, 
Col1 = table.Col1, 
Col2 = table.Col2 
} 

然後我想對結果執行SQL「WHERE ... IN ....」查詢。這工作正常使用以下。 (返回與ID的ID1 ID2 ID3或結果)

sQuery = "ID1,ID2,ID3"; 
string[] aSearch = sQuery.Split(','); 
items = items.Where(i => aSearch.Contains(i.ID)); 

我想做什麼就能做的,是執行相同的操作,但沒有指定i.ID部分。所以,如果我有字段名稱的字符串,我想應用「WHERE IN」子句,我怎麼能在.Contains()方法中使用它?

回答

3

有幾種方法可以做到這一點。一種方法是使用Dynamic Linq。另一種方法是使用Predicate Builder

+0

羅伯特,謝謝你的帖子。 動態Linq看起來像它會允許我指定該字段爲基於字符串的查詢,這是我想要的,但我不確定它是否支持SQL IN子句。 Predicate Builder看起來像我可以通過鏈接Predicate.Or表達式來創建一個表達式,但是我不知道如何在這些表達式中使用我的列名稱字符串。我試圖通過反思,並調用Equals方法,但沒有運氣。 – matt 2010-05-06 10:24:33

1

你必須建立一個表達式樹。它最終會看起來像這樣(部分代碼,不會編譯)。這個包含和等於。用於此項目:http://weblogs.asp.net/rajbk/archive/2010/04/15/asp-net-mvc-paging-sorting-filtering-a-list-using-modelmetadata.aspx

var param = Expression.Parameter(filterType, propertyName); 
var left = Expression.Property(param, filterType.GetProperty(propertyName)); 
var right = Expression.Constant(propertyValue, modelMetaData.ModelType); 

LambdaExpression predicate = null; 

if (searchFilterAttribute.FilterType == FilterType.Contains) 
{ 
    var methodContains = typeof(string).GetMethod("Contains", new[] { typeof(string) }); 
    var filterContains = Expression.Call(left, methodContains, right); 
    predicate = Expression.Lambda(filterContains, param); 
} 
else 
{ 
    var expr = Expression.Equal(left, right); 
    predicate = Expression.Lambda(expr, param); 

} 

var expression = Expression.Call(
    typeof(Queryable), 
    "Where", 
    new Type[] { queryable.ElementType }, 
    queryable.Expression, 
    predicate); 

queryable = queryable.Provider.CreateQuery<T>(expression); 

我可以改寫這個成可重複使用的擴展方法(這是過於具體到該項目目前)和博客了。

+0

感謝您的回答拉傑,但我認爲這將允許我檢查一個字段是否包含字符串。我想要使​​用contains執行一個SQL IN等效項。即數組包含字段,而不是字段包含字符串。 – matt 2010-05-06 09:30:16