Динамическое «ГДЕ ВХОД» на IQueryable (linq to SQL) - PullRequest
4 голосов
/ 05 мая 2010

У меня есть запрос 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 ...." по результатам. Это прекрасно работает, используя следующее. (вернуть результаты с идентификатором 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 ]

3 голосов
/ 05 мая 2010

Есть несколько способов сделать это. Одним из способов является использование Dynamic Linq . Другой способ - использовать Predicate Builder .

1 голос
/ 05 мая 2010

Вы должны построить дерево выражений. В конечном итоге это будет выглядеть так (частичный код не будет компилироваться). Этот делает и содержит и равных. Используется в этом проекте: 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);

Я могу переписать это в метод расширения многократного использования (на данный момент он слишком специфичен для этого проекта) и написать об этом в блоге.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...