组合两个表达式
本文关键字:两个 表达式 组合 | 更新日期: 2023-09-27 17:54:44
我试图创建一个用于实体框架查询的表达式。我创建了两个表达式:
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(long additionId)
{
return x => x.PriceDefinition.AdditionsPrices.Any(a => a.AdditionId == additionId);
}
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
long? inviterId, long? routeId, long? luggageTypeId)
{
return x =>
(inviterId.HasValue || routeId.HasValue || luggageTypeId.HasValue) &&
!(
(x.PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
PriceDefinition.InviterId.Value != inviterId.Value) ||
(PriceDefinition.LuggageTypeId.HasValue && luggageTypeId.HasValue &&
PriceDefinition.LuggageTypeId.Value != luggageTypeId.Value) ||
(PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
PriceDefinition.InviterId.Value != inviterId.Value)
);
}
现在我愿意把它们结合起来:
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
long? inviterId, long? routeId, long? luggageTypeId, long additionId)
{
return IsMatchExpression(inviterId, routeId, luggageTypeId) &&
IsMatchExpression(additionId);
}
这个方法不能编译。我也觉得我做错了什么。我该怎么修理它?
编辑:
我忘了重要的部分!问题更新
您必须直接使用表达式组件来完成此操作。
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
long? inviterId, long? routeId, long? luggageTypeId, long additionId)
{
var a = IsMatchExpression(inviterId, routeId, luggageTypeId);
var b = IsMatchExpression(additionId);
var p = Expression.Parameter(typeof(IEntityPriceDefinition),"x");
var c = Expression.AndAlso(Expression.Invoke(a,p),Expression.Invoke(b,p));
var r = Expression.Lambda<Func<IEntityPriceDefinition, bool>>(c,p);
return r;
}
这可以通过从两个表达式中分离出.Body
并用新参数替换(使用ExpressionVisitor
)参数来使其更复杂;并且您的两个工作方法中的每一个都可以更改以将其参数绑定到ConstantExpression
s中,从而完全失去lambda表达式语法。这些变化实际上可能是必要的,使一个表达式,可以与实体框架正常工作,但这将需要一些时间,我工作出来张贴在答案。
参见我如何从较小的,可重复使用的查询组成实体框架查询?
ok,会是这样吗
var x = IsMatchExpression(inviterId, routeId, luggageTypeId)
var y = IsMatchExpression(additionId);
return arg => x(arg) && y(arg)
?
刚刚创建的组合方法:
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
long? inviterId, long? routeId, long? luggageTypeId, long additionId)
{
return x =>
(inviterId.HasValue || routeId.HasValue || luggageTypeId.HasValue) &&
(x.PriceDefinition.AdditionsPrices.Any(a => a.AdditionId == additionId)) &&
!(
(x.PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
PriceDefinition.InviterId.Value != inviterId.Value) ||
(PriceDefinition.LuggageTypeId.HasValue && luggageTypeId.HasValue &&
PriceDefinition.LuggageTypeId.Value != luggageTypeId.Value) ||
(PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
PriceDefinition.InviterId.Value != inviterId.Value)
);
}