C# lambda中的动态where子句

C# lambda中的动态where子句,c#,lambda,C#,Lambda,我正在使用实体框架,我需要创建一个动态表达式,如: var sel = Expression.Lambda<Func<TEntity, bool>>(propertyAccess, parameter); var compiledSel = sel.Compile(); // sel = x.Name // filter.Value = "John" Repository.GetData.Where(item => compiledSel(item) != null

我正在使用实体框架,我需要创建一个动态表达式,如:

var sel = Expression.Lambda<Func<TEntity, bool>>(propertyAccess, parameter);
var compiledSel = sel.Compile();
// sel = x.Name
// filter.Value = "John"
Repository.GetData.Where(item => compiledSel(item) != null && compiledSel(item).ToLower().StartsWith(filter.Value.ToString().ToLower()))
到,例如

x => x.Name != null && x.Name.StartsWith("John")
我这样做的原因是因为我有多个实体,我希望能够动态过滤

有什么建议吗

编辑:

针对EF的查询本身在此处运行:

private IList<TEntity> GetCollection(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, object>>[] includes)
{
    return DbSet 
     .Where(where)
     .ApplyIncludes(includes)
     .ToList();
}
private IList GetCollection(表达式,其中,表达式[]包括)
{
返回数据集
.Where(Where)
.ApplyIncludes(包括)
.ToList();
}

当我现在运行查询时,data where子句是
Param_0=>((Invoke(value(..
和I get
LINQ to Entities中不支持LINQ表达式节点类型“Invoke”。
error

动态LINQ可能是您的一个选项:

Repository.People.Where("Name != null && Name.StartsWith(\"John\")")

首先,如果
propertyAccess
是字符串属性的访问器,则

var sel = Expression.Lambda<Func<TEntity, bool>>(propertyAccess, parameter);
以下是所用帮助器方法的代码:

public static class ExpressionUtils
{
    public static Expression ReplaceParameter(this Expression expression, ParameterExpression source, Expression target)
    {
        return new ParameterReplacer { Source = source, Target = target }.Visit(expression);
    }

    class ParameterReplacer : ExpressionVisitor
    {
        public ParameterExpression Source;
        public Expression Target;
        protected override Expression VisitParameter(ParameterExpression node)
        {
            return node == Source ? Target : base.VisitParameter(node);
        }
    }
}

如何向您的实体添加一个接口?例如,
class MyEntity:INameable
带有属性
string Name
,然后您可以使用
Func
动态
propertyaaccess
变量包含哪些内容?字符串属性访问器?因此
sel
实际上是
Expression
而不是
Expressionn
如示例中所示?添加不可数的问题在于,我有许多不同的实体,因此“x.Name”只是一个示例,它可能是相当多的其他内容。在这个示例中,propperyAccess包含一个MemberExpression{x.Name}我很确定您使用的是重载
IEnumerable.Where(Func)
重载,它接受一个
Func
而不是
IQueryable。其中(表达式)
接受一个表达式。您的问题不是“它与IQueryable一起工作,但与EF不一起工作”。
var sel = Expression.Lambda<Func<TEntity, string>>(propertyAccess, parameter);
var selector = Expression.Lambda<Func<TEntity, string>>(propertyAccess, parameter);

var value = filter.Value.ToString().ToLower();

Expression<Func<string, bool>> prototype = 
    item => item != null && item.ToLower().StartsWith(value);

var predicate = Expression.Lambda<Func<T, bool>>(
    prototype.Body.ReplaceParameter(prototype.Parameters[0], selector.Body), 
    selector.Parameters[0]);
public static class ExpressionUtils
{
    public static Expression ReplaceParameter(this Expression expression, ParameterExpression source, Expression target)
    {
        return new ParameterReplacer { Source = source, Target = target }.Visit(expression);
    }

    class ParameterReplacer : ExpressionVisitor
    {
        public ParameterExpression Source;
        public Expression Target;
        protected override Expression VisitParameter(ParameterExpression node)
        {
            return node == Source ? Target : base.VisitParameter(node);
        }
    }
}