gpt4 book ai didi

c# - lambda 中的动态 where 子句

转载 作者:太空狗 更新时间:2023-10-30 01:15:14 25 4
gpt4 key购买 nike

我正在使用 Entity Framework ,我需要创建一个动态表达式,例如:

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()))

以上适用于 IQueriable,但我需要它才能与 Entity Framework 一起使用。

这意味着我需要解析

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();
}

当我现在运行查询时,数据 where 子句是 Param_0 => (((Invoke(value(.... 并且我得到 The LINQ expression node type 'Invoke' is LINQ to Entities 不支持。 错误

最佳答案

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

var sel = Expression.Lambda<Func<TEntity, bool>>(propertyAccess, parameter);

应该是

var sel = Expression.Lambda<Func<TEntity, string>>(propertyAccess, parameter);

其次,Compile 在 EF 表达式中不起作用。您可以使用 Expression 类的方法手动构建整个谓词表达式,但这相对困难。我可以建议您使用“原型(prototype)”表达式和简单的参数替换器,如下所示:

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);
}
}
}

关于c# - lambda 中的动态 where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39205653/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com