Search code examples
c#linqasp.net-coreprojection

Dynamic Projection using DynamicExpressionParser ParseLambda


I'm trying to convert some code that creates a dynamic projection from .Net 4.5 to .Net Core 3; I have the following code in .Net 4.5

var e = DynamicExpression.ParseLambda(
                typeof(MyModel),
                typeof (object),
                "new(Id as id)");

ParseLambda is not available on DynamicExpression in .Net Core 3, so I changed the code to:

var e = DynamicExpressionParser.ParseLambda(
            typeof(MyModel),
            typeof (object),
            "new(Id as id)");

But this results in a null reference exception with the following stack trace

   at System.Linq.Dynamic.Core.Parser.ExpressionParser.CreateNewExpression(List`1 properties, List`1 expressions, Type newType)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNew()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIdentifier()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParsePrimary()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseUnary()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseMultiplicative()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAdditive()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseShiftOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseComparisonOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLogicalAndOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIn()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAndOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLambdaOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNullCoalescingOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseConditionalOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.Parse(Type resultType, Boolean createParameterCtor)
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values)
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(Boolean createParameterCtor, Type itType, Type resultType, String expression, Object[] values)
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(Type itType, Type resultType, String expression, Object[] values)

The code works fine when the expression is "Id == 0" or any other comparison, but I cannot get the "new" expression to work...


Solution

  • Passing typeof(object) as the result type works with the .Net 4.5 implementation of ParseLambda, but after reviewing the System.Linq.Dynamic.Core source code, I found that ParseLambda can take a result type of null. The following code works as expected in .Net Core 3.

    var e = DynamicExpressionParser.ParseLambda(
              typeof(MyModel),  // itType
              null,             // resultType
              "new(Id as id)"); // expression
    

    https://github.com/StefH/System.Linq.Dynamic.Core/blob/master/src/Microsoft.EntityFrameworkCore.DynamicLinq/EFDynamicQueryableExtensions.cs