表达式树产生参数异常
Expression tree yields Argument exception
我有以下代码,一切正常,直到我到达最后一行失败并出现以下异常:
Method 'Boolean Contains(System.Linq.Expressions.ConstantExpression)' declared on type 'System.Collections.Generic.List`1[System.Linq.Expressions.ConstantExpression]' cannot be called with instance of type 'System.Guid'
var filter = new List<SomeObj> { new SomeObj { Id = "<guid-string>" }};
var lookupExpression = filter.SetOperand.Select(x => Expression.Constant(Guid.Parse(x.Id))).ToList();
var arrayOfValues = Expression.NewArrayInit(typeof(Guid), lookupExpression);
var arrayType = lookupExpression.GetType();
var containsMethod = arrayType.GetMethod("Contains");
var right = Expression.Call(dataProperty, containsMethod, arrayOfValues);
我认为问题在于 dataProperty 是从动态构造的表达式中读取的,该表达式始终是 Guid,因此当方法执行时,它将此对象视为 Guid,而方法和列表都是 List。还有其他解决方法吗?
我不太明白你想做什么或为什么,但这是我猜测如何修复你的代码:
- 您不想检查您的 GUID 表达式集合 (
lookupExpression
) 是否包含给定的 GUID,您想要检查您的 GUID 集合 (arrayOfValues
) 可以。也就是说arrayType
是错误的,应该是:var arrayType = arrayOfValues.Type;
.
如果arrayOfValues
实际上是数组,你不能使用Contains
实例方法,因为数组没有。
您可以使用 LINQ Contains
,或将 arrayOfValues
更改为表示 List<Guid>
而不是 Guid[]
的表达式。我选择了 LINQ。
获取LINQ Contains
方法,可以使用LINQ:
var containsMethod = typeof(Enumerable).GetMethods()
.Single(m => m.Name == "Contains" && m.GetParameters().Length == 2)
.MakeGenericMethod(typeof(Guid));
您的 Call()
顺序错误,即使 List.Contains()
也是如此。对于 LINQ Contains
,正确的顺序是:
Expression.Call(containsMethod, arrayOfValues, dataProperty)
我有以下代码,一切正常,直到我到达最后一行失败并出现以下异常:
Method 'Boolean Contains(System.Linq.Expressions.ConstantExpression)' declared on type 'System.Collections.Generic.List`1[System.Linq.Expressions.ConstantExpression]' cannot be called with instance of type 'System.Guid'
var filter = new List<SomeObj> { new SomeObj { Id = "<guid-string>" }};
var lookupExpression = filter.SetOperand.Select(x => Expression.Constant(Guid.Parse(x.Id))).ToList();
var arrayOfValues = Expression.NewArrayInit(typeof(Guid), lookupExpression);
var arrayType = lookupExpression.GetType();
var containsMethod = arrayType.GetMethod("Contains");
var right = Expression.Call(dataProperty, containsMethod, arrayOfValues);
我认为问题在于 dataProperty 是从动态构造的表达式中读取的,该表达式始终是 Guid,因此当方法执行时,它将此对象视为 Guid,而方法和列表都是 List。还有其他解决方法吗?
我不太明白你想做什么或为什么,但这是我猜测如何修复你的代码:
- 您不想检查您的 GUID 表达式集合 (
lookupExpression
) 是否包含给定的 GUID,您想要检查您的 GUID 集合 (arrayOfValues
) 可以。也就是说arrayType
是错误的,应该是:var arrayType = arrayOfValues.Type;
. 如果
arrayOfValues
实际上是数组,你不能使用Contains
实例方法,因为数组没有。您可以使用 LINQ
Contains
,或将arrayOfValues
更改为表示List<Guid>
而不是Guid[]
的表达式。我选择了 LINQ。获取LINQ
Contains
方法,可以使用LINQ:var containsMethod = typeof(Enumerable).GetMethods() .Single(m => m.Name == "Contains" && m.GetParameters().Length == 2) .MakeGenericMethod(typeof(Guid));
您的
Call()
顺序错误,即使List.Contains()
也是如此。对于 LINQContains
,正确的顺序是:Expression.Call(containsMethod, arrayOfValues, dataProperty)