组合两个表达式

发布于 2024-11-04 04:55:52 字数 1491 浏览 0 评论 0原文

我正在尝试创建一个用于实体框架查询的表达式。 我创建了两个表达式:

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);
    }

此方法无法编译。我也有一种感觉,我做错了什么。我该如何修复它?

编辑:
我忘记了重要的部分!问题已更新。

I am trying to create an expression for using in entity framework query.
I created two expressions:

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)
        );
}

And now I am willing to combine them:

    public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
        long? inviterId, long? routeId, long? luggageTypeId, long additionId)
    {
        return IsMatchExpression(inviterId, routeId, luggageTypeId) &&
                IsMatchExpression(additionId);
    }

This method doesn't compiles. I also have the feeling I did something wrong. How can I fix it?

EDIT:
I forgotenn importent part! the question updated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╄→承喏 2024-11-11 04:55:52

您必须直接使用表达式组件才能执行此操作。

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中,从而完全失去lambda表达式语法。事实上,为了创建一个可以与实体框架正常工作的表达式,这些更改可能是必要的,但这需要我花一些时间才能发布在答案中。

另请参阅如何组合实体来自较小的、可重复使用的查询的框架查询?

You'll have to work with the expression components directly to do this.

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;
}

This could be made more sophisticated by breaking out the .Body from each of the two expressions and replacing (using an ExpressionVisitor) the parameters with the new parameter; and each of your two working methods could be changed to bind their parameters into ConstantExpressions, losing the lambda expression syntax altogether. Those changes may in fact be necessary to make an expression that can work properly with entity framework, but this will take some time for me to work out to post in the answer.

See also How can I compose an Entity Framework query from smaller, resusable queries?

小女人ら 2024-11-11 04:55:52

好吧,可以是这样吗

var x = IsMatchExpression(inviterId, routeId, luggageTypeId)
var y = IsMatchExpression(additionId);
return arg => x(arg) && y(arg) 

ok could it be sth like

var x = IsMatchExpression(inviterId, routeId, luggageTypeId)
var y = IsMatchExpression(additionId);
return arg => x(arg) && y(arg) 

?

宫墨修音 2024-11-11 04:55:52

刚刚创建的组合方法:

   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)
        );
}

不是最好的解决方案,但它有效。

Just created combined method:

   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)
        );
}

Not the best solution but it works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文