带有List <t>的表达式函数.Select()。包含()

时间:2016-08-03 14:25:06

标签: c# entity-framework linq

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

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<MemberInfo>

由于

1 个答案:

答案 0 :(得分: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();
}