带有列表的表达式函数<;T>;.选择().Contains()
本文关键字:Contains gt 选择 lt 列表 表达式 函数 | 更新日期: 2023-09-27 17:59:55
这是我的通用存储库类方法:
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>
感谢
您的方法是可以的。但您需要将成员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();
}