需要帮助转换“Any()” lambda到表达式树 [英] Need help converting "Any()" lambda to an expression tree

查看:180
本文介绍了需要帮助转换“Any()” lambda到表达式树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下几点。 (这是有效的,但是我需要帐号作为一个字符串传递。帐户是帐户列表)

Consider the following. (which works, but I need Accounts to be passed in as a string. Accounts is list of Account)

repo = repo.Where(x => x.Accounts.Any(p => p.Id == 1));

这是我到目前为止,但我似乎无法将它们连线在一起。

Here is what I have so far, but I can't seem to wire them together at the end.

        var parameterExp = Expression.Parameter(typeof(Car), "x");
        Expression propertyExp = Expression.Property(parameterExp, "Accounts");

        //Type elementType = propertyExp.Type.GetGenericArguments()[0];

        MethodInfo AnyMethod = typeof(Enumerable).GetMethods(BindingFlags.Public | BindingFlags.Static).First(m => m.Name == "Any");

        var parameterExp2 = Expression.Parameter(typeof(Car), "p");

        var idExpr = Expression.PropertyOrField(parameterExp2, "Id");

        MethodInfo method = typeof(long).GetMethod("Equals", new[] { typeof(long) });
        var _relatedToId = Expression.Constant(relatedToId, typeof(long));
        var equalsMethodExp = Expression.Call(idExpr, method, _relatedToId);

        // This is where it breaks. I can't seem to wire it together correctly.
        var call = Expression.Call(
            AnyMethod,
            propertyExp,
            equalsMethodExp);

        Expression<Func<Car, bool>> predicate = Expression.Lambda<Func<Car, bool>>(call, parameterExp);

        // Need to return x => x.Accounts.Any(p => p.Id.Equals(1))
        return predicate;

提前感谢

推荐答案

您有几个错误:


  • 首先,取消注释下面的

  • Firstly, uncomment line below

Type elementType = propertyExp.Type.GetGenericArguments()[0];


  • 其次,您不正确地检索 MethodInfo 任何。您需要包含两个参数(source,func)的信息,您需要获取任何任何< Account> 的封闭类型,而不是打开 Any< < / code>:

  • Secondly, you don't correctly retrieve MethodInfo for Any. You need info that contains two parameters (source, func) and you need to get the closed type of Any Any<Account> not the open Any<>:

    MethodInfo AnyMethod = typeof(Enumerable)
                           .GetMethods(BindingFlags.Public | BindingFlags.Static)
                           .First(m => m.Name == "Any" && m.GetParameters().Length > 1);
    var closedAnyMethod = AnyMethod.MakeGenericMethod(elementType);
    


  • 第三, parameterExp2 。它应该是帐户汽车

    var parameterExp2 = Expression.Parameter(elementType, "p");
    


  • 第四,你应该转换一个 MethodCallExpression for 等于方法到lambda表达式。您不能直接将等于'调用表达式传递给任何,因为任何获取 Func< T,bool> 作为参数:

  • Fourthly, you should convert a MethodCallExpression for Equals method to lambda expression. You cannot directly pass Equals' call expression to Any because Any gets Func<T, bool> as parameter:

    var equalsMethodExp = Expression.Call(idExpr, method, _relatedToId);
    var lambdaAny = Expression.Lambda(typeof(Func<,>).MakeGenericType(elementType, typeof(bool)), equalsMethodExp, parameterExp2);
    


  • 最后,您只需要调用另一个覆盖 Expression即可。调用

    var call = Expression.Call(
            closedAnyMethod,
            propertyExp,
            lambdaAny);
    


  • 让我知道如果你想得到完整的代码。

    Let me know if you want to get the complete code.

    这篇关于需要帮助转换“Any()” lambda到表达式树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆