使用 DynamicExpressionParser ParseLambda 的动态投影
Dynamic Projection using DynamicExpressionParser ParseLambda
我正在尝试将一些创建动态投影的代码从 .Net 4.5 转换为 .Net Core 3;我在 .Net 4.5
中有以下代码
var e = DynamicExpression.ParseLambda(
typeof(MyModel),
typeof (object),
"new(Id as id)");
ParseLambda 在 .Net Core 3 中的 DynamicExpression 上不可用,所以我将代码更改为:
var e = DynamicExpressionParser.ParseLambda(
typeof(MyModel),
typeof (object),
"new(Id as id)");
但这会导致空引用异常并出现以下堆栈跟踪
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)
当表达式为 "Id == 0" 或任何其他比较时代码工作正常,但我无法使 "new" 表达式工作...
听起来您正在使用 System.Linq.Dynamic.Core。
如果是这种情况,您需要确保输出类型获得 id
的 属性。您的代码将不起作用,因为您的输出类型是 object
。由于 object
没有得到 id
属性,它失败了。
由于类似的原因,您还需要确保输入类型获得 属性 的 Id
。
诀窍是始终使用一致的属性。例如,假设您有两种类型:
public class MyInput // input
{
public int Id { get; set; }
}
public class MyOutput // output
{
public int id { get; set; }
}
您可以按如下方式解析字符串:
var e = DynamicExpressionParser.ParseLambda(
typeof(MyInput), // input type
typeof(MyOutput), // output type
"new (Id as id)"); // initialize properties
// test
MyOutput o = e.Compile().DynamicInvoke(new MyInput() { Id = 123 }) as MyOutput;
Console.WriteLine(o.id); // outputs 123
传递 typeof(object) 作为结果类型适用于 ParseLambda 的 .Net 4.5 实现,但在查看 System.Linq.Dynamic.Core 源代码后,我发现 ParseLambda 可以采用 null 结果类型。以下代码在 .Net Core 3 中按预期工作。
var e = DynamicExpressionParser.ParseLambda(
typeof(MyModel), // itType
null, // resultType
"new(Id as id)"); // expression
我正在尝试将一些创建动态投影的代码从 .Net 4.5 转换为 .Net Core 3;我在 .Net 4.5
中有以下代码var e = DynamicExpression.ParseLambda(
typeof(MyModel),
typeof (object),
"new(Id as id)");
ParseLambda 在 .Net Core 3 中的 DynamicExpression 上不可用,所以我将代码更改为:
var e = DynamicExpressionParser.ParseLambda(
typeof(MyModel),
typeof (object),
"new(Id as id)");
但这会导致空引用异常并出现以下堆栈跟踪
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)
当表达式为 "Id == 0" 或任何其他比较时代码工作正常,但我无法使 "new" 表达式工作...
听起来您正在使用 System.Linq.Dynamic.Core。
如果是这种情况,您需要确保输出类型获得 id
的 属性。您的代码将不起作用,因为您的输出类型是 object
。由于 object
没有得到 id
属性,它失败了。
由于类似的原因,您还需要确保输入类型获得 属性 的 Id
。
诀窍是始终使用一致的属性。例如,假设您有两种类型:
public class MyInput // input
{
public int Id { get; set; }
}
public class MyOutput // output
{
public int id { get; set; }
}
您可以按如下方式解析字符串:
var e = DynamicExpressionParser.ParseLambda(
typeof(MyInput), // input type
typeof(MyOutput), // output type
"new (Id as id)"); // initialize properties
// test
MyOutput o = e.Compile().DynamicInvoke(new MyInput() { Id = 123 }) as MyOutput;
Console.WriteLine(o.id); // outputs 123
传递 typeof(object) 作为结果类型适用于 ParseLambda 的 .Net 4.5 实现,但在查看 System.Linq.Dynamic.Core 源代码后,我发现 ParseLambda 可以采用 null 结果类型。以下代码在 .Net Core 3 中按预期工作。
var e = DynamicExpressionParser.ParseLambda(
typeof(MyModel), // itType
null, // resultType
"new(Id as id)"); // expression