dynamicexpresso / DynamicExpresso

C# expressions interpreter
http://dynamic-expresso.azurewebsites.net/
MIT License
1.91k stars 364 forks source link

Select Linq not working with more than one parameter #259

Closed sachindevtomar closed 1 year ago

sachindevtomar commented 1 year ago

Hello Team,

I want to use following expression but it is throwing error "UnknownIdentifierException 'visualCount' ". Following expression is fine fine when select linq has only single property i.e. pageName or visualCount.

var options = InterpreterOptions.Default | InterpreterOptions.LambdaExpressions; 
var interpreter = new Interpreter(options).SetVariable("courseList", courseList);

string expression = @"courseList.Select(x =>  new { pageName = x.PageName , visualCount = 5 })";

Lambda parsedExpression = interpreter.Parse(expression);
var result = parsedExpression.Invoke();

Note: I have tried every property, each time it worked for single property but not for multiple properties.

Please resolve this issue as I am currently blocked.

davideicardi commented 1 year ago

Thank you @sachindevtomar for the bug report. This is a free and open source project, we cannot guarantee any kind of support, but any contribution and help is appreciated.

metoule commented 1 year ago

I'm surprised it even works with a single property, because anonymous types are not supported (see #75). Can you share an example where it's working?

metoule commented 1 year ago

I managed to reproduce, and it's indeed a bug with the way we determine where the body of a lambda expression ends:

[Test]
public void Lambda_Issue_259()
{
    var options = InterpreterOptions.Default | InterpreterOptions.LambdaExpressions;
    var interpreter = new Interpreter(options);
    interpreter.SetVariable("courseList", new[] { new { PageName = "Test" } });
    interpreter.Reference(typeof(PageType));

    var results = interpreter.Eval<IEnumerable<PageType>>(@"courseList.Select(x => new PageType() { PageName = x.PageName, VisualCount = 5 })");
    Assert.AreEqual(1, results.Count());

    var result = results.Single();
    Assert.AreEqual("Test", result.PageName);
    Assert.AreEqual(5, result.VisualCount);
}

public class PageType
{
    public string PageName { get; set; }
    public int VisualCount { get; set; }
}