Во-первых, вам нужно сохранить столбец как выражение, иначе c# скомпилирует лямбда-функцию, и EF не сможет извлечь, какой это столбец;
protected Expression<Func<T, TColumn>> GetColumn;
public MyClass(Expression<Func<T, TColumn>> getColumn)
{
GetColumn = getColumn;
}
Теперь вы можете использовать методы stati c из Expression
для создания полного выражения фильтра вручную. Но в вашем случае есть ярлык. Поскольку вы можете повторно использовать параметр и тело входного выражения (например, x => x.Column
) и обернуть его в свой вызов Contains
(например, x => FilterIds.Contains(x.Column)
).
EDIT:
Поскольку теперь вы выяснили, что FilterIds
- это IEnumerable<T>
, то FilterIds.Contains()
на самом деле является методом расширения stati c Enumerable.Contains()
. Самый простой способ найти подходящий метод generi c stati c - создать соответствующий делегат.
public virtual IQueryable<T> ApplyFilter(IQueryable<T> query)
{
if (FilterMode == FilterModeMatchAny)
return query.Where(
Expression.Lambda<Func<T, bool>>(
Expression.Call(
null,
new Func<IEnumerable<TColumn>,TColumn,bool>(Enumerable.Contains).Method,
Expression.Constant(FilterIds),
GetColumn.Body),
GetColumn.Parameters)
);
return query;
}
EDIT:
.Where(x => GetJoiningTables(x).Any(...
Хорошо, это банка с червями ... Я предполагаю, что вы пытаетесь здесь взять набор переходов к другим таблицам и столбцам и применить к ним фильтр?
Я считаю, что это помогает построить пример Expression
, которого вы пытаетесь достичь. Я предполагаю, что вы пытаетесь построить такие выражения, как;
Expression<Func<T,bool>> filter = t =>
Enumerable.Any(t.Child1, c => FilterIds.Contains(c.ChildCol))
|| Enumerable.Any(t.Child2, c => FilterIds.Contains(c.OtherChildCol))
... ;
Expression<Func<T,bool>> filter = t =>
Enumerable.Count(t.Child1, c => FilterIds.Contains(c.ChildCol))
+ Enumerable.Count(t.Child2, c => FilterIds.Contains(c.OtherChildCol))
... ;
Я предлагаю вам написать этот код, позволить компилятору c# превратить их в графики Expression
и использовать отладчик, чтобы увидеть, что это за графики выглядят так.
Если возможно, я бы порекомендовал найти способ «отдать цезарю то, что цезарю». И собрать фрагменты Expression
s путем встраивания или преобразования некоторого шаблона Expression
.