我正在尝试创建一个在实体框架查询中使用的表达式。 我创建了两个表达式:
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);
}
此方法无法编译。我也有感觉我做错了什么。我该如何解决?
修改
我忘记了重要部分!问题已更新。
答案 0 :(得分:1)
您必须直接使用表达式组件才能执行此操作。
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表达式语法。事实上,这些更改可能是必要的,以使表达能够与实体框架一起正常工作,但这需要一些时间让我在答案中发布。
另见How can I compose an Entity Framework query from smaller, resusable queries?
答案 1 :(得分:0)
好吧可能就像
var x = IsMatchExpression(inviterId, routeId, luggageTypeId)
var y = IsMatchExpression(additionId);
return arg => x(arg) && y(arg)
答案 2 :(得分:0)
刚刚创建了组合方法:
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)
);
}
不是最好的解决方案,但它有效。