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

it isn't interpreted as the inner parameter when using All or Any #440

Closed
zspitz opened this issue Oct 28, 2020 · 4 comments
Closed

it isn't interpreted as the inner parameter when using All or Any #440

zspitz opened this issue Oct 28, 2020 · 4 comments
Assignees
Labels

Comments

@zspitz
Copy link

zspitz commented Oct 28, 2020

The following code:

public class Person {
    public string LastName { get; set; |
}

var selector = "LastName.Any(int(it) > 109";
var prm = Parameter(typeof(Person));
var parser = new ExpressionParser(new[] { prm }, selector, new object[] { }, ParsingConfig.Default);
var expr = parser.Parse(null);

fails with:

System.Linq.Dynamic.Core.Exceptions.ParseException: 'A value of type 'Person' cannot be converted to type 'Int32''
while changing selector to this:

var selector = "LastName.Any(it == 'c')";

fails similarly with:

System.InvalidOperationException: 'The binary operator Equal is not defined for the types '_DynamicLINQ.Person' and 'System.Char'.'

It seems as though the it when used in the inner lambda is still interpreted as the outer it (in this case, Person and not char).

Note: I didn't test this with other LINQ methods.

This seems to run counter to the documentation:

In the predicate and selector expressions, the members of the current instance for that sequence operator are automatically in scope, and the instance itself can be referenced using the keyword it.

@zspitz zspitz changed the title it isn't interperted as the inner parameter when using All it isn't interperted as the inner parameter when using All or Any Oct 28, 2020
@JonathanMagnan
Copy link
Member

Hello @zspitz ,

I think you are currently trying to use the library in a way that it was not built for.

As said in the name, the library is made to execute LINQ query such as:

var list = new List<Person>();
list.Add(new Person() {LastName = "a"});
list.Add(new Person() {LastName = "b"});
list.Add(new Person() {LastName = "c"});

var x = list.AsQueryable().Any("it.LastName == \"c\"");

It's not initially intended to be a full C# evaluator. For those, there is our other library C# Eval Expression or perhaps even better for your case Roslyn Scripting.

While this library tries to support as much as possible, it doesn't support everything such as LINQ method in an expression.

@zspitz
Copy link
Author

zspitz commented Oct 30, 2020

@JonathanMagnan

While this library tries to support as much as possible, it doesn't support everything such as LINQ method in an expression.

The documentation suggests that the library does allow certain specific LINQ method calls, even in an expression. As part of the expression language syntax, it has this to say:

A subset of the Standard Query Operators is supported for objects that implement IEnumerable<T> or IQueryable<T>. Specifically, the following constructs are permitted, where seq is an IEnumerable<T> or IQueryable<T> instance, predicate is a boolean expression and selector is an expression of any type.
...
In the predicate and selector expressions, the members of the current instance for that sequence operator are automatically in scope, and the instance itself can be referenced using the keyword it. For example:

customers.Where("Orders.Any(Total >= 1000)");

Note that this is distinct from the extension methods provided by Dynamic LINQ.

Here you can see the code which parses specific Enumerable / Queryable methods within the Dynamic LINQ string; and it's called from here.

@zspitz
Copy link
Author

zspitz commented May 10, 2021

AFAICT the primary issue is that it already refers to the outer lambda parameter; how should it refer to the inner lambda parameter?

But one way to resolve this might be to allow numbered its: it0 (equivalent to it), it1, it2 etc. This would allow accessing multiple levels of inner lambda parameters.

@JonathanMagnan @StefH Any news/thoughts on this?

@StefH StefH changed the title it isn't interperted as the inner parameter when using All or Any it isn't interpreted as the inner parameter when using All or Any Aug 4, 2021
StefH added a commit that referenced this issue Apr 17, 2024
@StefH StefH added the bug label Apr 17, 2024
@StefH StefH self-assigned this Apr 17, 2024
@StefH
Copy link
Collaborator

StefH commented Apr 17, 2024

#798

@StefH StefH closed this as completed Apr 17, 2024
StefH added a commit that referenced this issue Apr 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants