IQueryable上的动态“WHERE IN”(linq to SQL)

时间:2010-05-05 16:35:48

标签: c# linq-to-sql lambda

我有一个LINQ to SQL查询,将表中的行返回到IQueryable对象。

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()方法中使用它?

2 个答案:

答案 0 :(得分:3)

有几种方法可以做到这一点。一种方法是使用Dynamic Linq。另一种方法是使用Predicate Builder

答案 1 :(得分: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);

我可以将其重写为可重用的扩展方法(目前对于该项目来说太具体了)和博客。