【问题标题】:Expression Func with List<T>.Select().Contains()带有 List<T>.Select().Contains() 的表达式函数
【发布时间】:2016-08-03 14:25:05
【问题描述】:

这是我的通用存储库类方法:

public IEnumerable<T> GetBy(Expression<Func<T, bool>> condition)
    {
        return Context.Set<T>().Where(condition).ToList();
    }

我想这样称呼它:

resultCandidate = _repo.GetBy(p => members.Select(s=>s.MemberID).Contains(p.CandidateMemberID)).ToList();

但是当我尝试它时,它会抛出一个错误,例如“无法创建StateInfo 类型的常量值。此上下文中仅支持原始类型或枚举类型。”

我应该这样调用方法。我尝试condition.Compile() 并且它工作但没有像我想要的那样工作。因为它在生成 SQL 查询时没有得到 where 子句。

注意:成员是List&lt;MemberInfo&gt;

谢谢

【问题讨论】:

    标签: c# entity-framework linq


    【解决方案1】:

    你的方法没问题。但是您需要将成员 ID 列表移到表达式之外(这是异常消息试图指示的内容),从而满足 原始类型 列表要求:

    var memberIds = members.Select(s=>s.MemberID).ToList();
    resultCandidate = _repo.GetBy(p => memberIds.Contains(p.CandidateMemberID)).ToList();
    

    更新:好吧,如果你这么称呼它对你来说非常重要,那么你可以尝试以下非常幼稚的ExpressionVisitor

    using System.Linq.Expressions;
    
    class ExpandSelectVisitor : ExpressionVisitor
    {
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            if (node.Method.DeclaringType == typeof(Enumerable) && node.Method.Name == "Select")
                return Expression.Constant(Expression.Lambda(node).Compile().DynamicInvoke());
            return base.VisitMethodCall(node);
        }
    }
    

    并在您的通用存储库方法中使用它,如下所示:

    public IEnumerable<T> GetBy(Expression<Func<T, bool>> condition)
    {
        condition = condition.Update(
            new ExpandSelectVisitor().Visit(condition.Body), condition.Parameters);
    
        return Context.Set<T>().Where(condition).ToList();
    }
    

    【讨论】:

    • 是的@IvanStoev 它有效。但我应该在方法中使用它,因为它是一个大项目,我无法做到每一部分。应该和我写的一样
    • 不幸的是,没有其他方法可以使其符合当前的 EF 要求。
    • 表达式条件有什么可做的吗?当我使用condition.Compile() 时,它实际上可以工作,但正如我所说,它不会生成带有 where 子句的代码,而只会从中选择。
    • 如果编译表达式,那么查询过滤器将在内存中执行(加载整个表后),更糟糕。
    • 感谢您的帮助。那么我们可以不加表情地做到这一点吗?通过仅使用功能?必须是加载前过滤的表达式?
    猜你喜欢
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多