Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Predicate.Invoke(Predicate.Invoke(..)) does not work #22

Closed
matkoerner opened this issue May 28, 2015 · 0 comments
Closed

Predicate.Invoke(Predicate.Invoke(..)) does not work #22

matkoerner opened this issue May 28, 2015 · 0 comments

Comments

@matkoerner
Copy link

ExpressionExpander.VisitMethodCall; "Invoke"-Resolver (lines 65-85) is not resolving the case that one of the direct arguments in Invoke(..) is a call to another .Invoke.

Example:

System.Linq.Expressions.Expression<Func<string, string[], IEnumerable<string>>> PredicateFoo =
    (par1, par2) => par1.Split(par2, StringSplitOptions.None); // Just some stuff

System.Linq.Expressions.Expression<Func<string, string[], IEnumerable<string>>> PredicateInnerInvoke =
    (par1, par2) => PredicateFoo.Invoke(par1, par2); // Invoke

System.Linq.Expressions.Expression<Func<string, string[], IEnumerable<string>>> PredicateOuterInvoke =
    (par1, par2) => PredicateFoo.Invoke(PredicateInnerInvoke.Invoke(par1, par2).First(), par2); // Invoke(Invoke(..))

var bad = PredicateOuterInvoke.Expand().ToString();
// bad == (par1, par2) => value(xyz+<>c__DisplayClass2).PredicateOuterInvoke.Invoke(par1, par2).First().Split(par2, None)
// There is still a call to .Invoke here; Entity Framework does not know how to handle this
// Expected (no .Invoke anymore):
// good == (par1, par2) => par1.Split(par2, None).First().Split(par2, None)

We resolved this by using the following (very simple & not correct) Expand method:

public static Expression<TDelegate> ExpandEx<TDelegate>(this Expression<TDelegate> expr)
{
    while (expr.ToString().Contains(".Invoke"))
    {
        expr = LinqKit.Extensions.Expand(expr); // Expand will not expand all .Invoke calls, so do it recursively
    }
    return expr;
}

Our real life example:
Predicate1(X) = Get all users where X
Predicate2(X) = Get all users and their deputies from (Get all users where X)
so we are calling Predicate2.Invoke(Predicate1.Invoke(X)) and this fails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant