[英]Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' of method 'Boolean Equals(System.Object)'
i have one common grid view column filter method that filter grid view record with ColumnName and SearchText wise. 我有一个常见的网格视图列筛选器方法,使用ColumnName和SearchText明智地筛选网格视图记录。 here when i operate on nullable int datacolumn there is error thrown from this method like : 这里当我在nullable int数据列上操作时,从这个方法抛出错误,如:
Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' of method 'Boolean Equals(System.Object)' 类型'System.Int32'的表达式不能用于方法'Boolean Equals(System.Object)'的'System.Object'类型的参数
my method code is : 我的方法代码是:
public static IQueryable<T> FilterForColumn<T>(this IQueryable<T> queryable, string colName, string searchText)
{
if (colName != null && searchText != null)
{
var parameter = Expression.Parameter(typeof(T), "m");
var propertyExpression = Expression.Property(parameter, colName);
System.Linq.Expressions.ConstantExpression searchExpression = null;
System.Reflection.MethodInfo containsMethod = null;
// this must be of type Expression to accept different type of expressions
// i.e. BinaryExpression, MethodCallExpression, ...
System.Linq.Expressions.Expression body = null;
Expression ex1 = null;
Expression ex2 = null;
switch (colName)
{
case "JobID":
case "status_id":
Int32 _int = Convert.ToInt32(searchText);
searchExpression = Expression.Constant(_int);
containsMethod = typeof(Int32).GetMethod("Equals", new[] { typeof(Int32) });
body = Expression.Call(propertyExpression, containsMethod, searchExpression);
break;
case "group_id":
Int32? _int1 = Convert.ToInt32(searchText);
searchExpression = Expression.Constant(_int1);
containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });
//Error throws from this line
body = Expression.Call(propertyExpression, containsMethod, searchExpression);
break;
case "FileSize":
case "TotalFileSize":
Int64? _int2 = Convert.ToInt64(searchText);
searchExpression = Expression.Constant(_int2);
containsMethod = typeof(Int64?).GetMethod("Equals", new[] { typeof(Int64?) });
body = Expression.Call(propertyExpression, containsMethod, searchExpression);
break;
// section for DateTime? properties
case "PublishDate":
case "Birth_date":
case "Anniversary_date":
case "Profile_Updated_datetime":
case "CompletedOn":
DateTime currentDate = DateTime.ParseExact(searchText, "dd/MM/yyyy", null);
DateTime nextDate = currentDate.AddDays(1);
ex1 = Expression.GreaterThanOrEqual(propertyExpression, Expression.Constant(currentDate, typeof(DateTime?)));
ex2 = Expression.LessThan(propertyExpression, Expression.Constant(nextDate, typeof(DateTime?)));
body = Expression.AndAlso(ex1, ex2);
break;
// section for DateTime properties
case "Created_datetime":
case "Reminder_Date":
case "News_date":
case "thought_date":
case "SubscriptionDateTime":
case "Register_datetime":
case "CreatedOn":
DateTime currentDate1 = DateTime.ParseExact(searchText, "dd/MM/yyyy", null);
DateTime nextDate1 = currentDate1.AddDays(1);
ex1 = Expression.GreaterThanOrEqual(propertyExpression, Expression.Constant(currentDate1));
ex2 = Expression.LessThan(propertyExpression, Expression.Constant(nextDate1));
body = Expression.AndAlso(ex1, ex2);
break;
default:
searchExpression = Expression.Constant(searchText);
containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
body = Expression.Call(propertyExpression, containsMethod, searchExpression);
break;
}
var predicate = Expression.Lambda<Func<T, bool>>(body, new[] { parameter });
return queryable.Where(predicate);
}
else
{
return queryable;
}
}
here is my query that i fired : 这是我解雇的问题:
var query = Helper.GetUsers().Where(u => u.Id != user_id).OrderByDescending(u => u.Register_datetime).Select(u => new
{
Id = u.Id,
Name = u.First_name + " " + u.Last_name,
IsActive = u.IsActive,
IsVerified = u.IsVerified,
Username = u.Username,
password = u.password,
Birth_date = u.Birth_date,
Anniversary_date = u.Anniversary_date,
status_id = u.status_id,
group_id = u.group_id,
Profile_Updated_datetime = u.Profile_Updated_datetime,
Register_datetime = u.Register_datetime
}).FilterForColumn(ColumnName, SearchText).ToList();
here i include my query.GetType().ToString() result for better understanding types of columns that i operate on it. 这里我包含了我的query.GetType()。ToString()结果,以便更好地理解我对其进行操作的列类型。
System.Collections.Generic.List`1[<>f__AnonymousType0`12[System.Int32,System.String,System.Boolean,System.Boolean,System.String,System.String,System.Nullable`1[System.DateTime],System.Nullable`1[System.DateTime],System.Int32,System.Nullable`1[System.Int32],System.Nullable`1[System.DateTime],System.DateTime]]
EDIT 编辑
Found the solution in this question . 在这个问题中找到了解决方案。 You need to convert the expression to Object
before calling the Equals(object)
method: 在调用Equals(object)
方法之前,需要将表达式转换为Object
:
var converted = Expression.Convert(searchExpression, typeof(object));
body = Expression.Call(propertyExpression, containsMethod, converted);
Nicodemus13 's suggestion of explicitly setting searchExpression
's type to Object
in the first place should work, too. Nicodemus13建议首先将searchExpression
的类型显式设置为Object
应该有效。
Original 原版的
I haven't found the issue yet, but I have reproduced the problem in a SSCCE using Linqpad: 我还没有找到问题,但我使用Linqpad在SSCCE中重现了这个问题:
void Main()
{
var myInstance = new myClass();
var equalsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });
int? nullableInt = 1;
var nullableIntExpr = System.Linq.Expressions.Expression.Constant(nullableInt);
var myInstanceExpr = System.Linq.Expressions.Expression.Constant(myInstance);
var propertyExpr = System.Linq.Expressions.Expression.Property(myInstanceExpr, "MyProperty");
var result = Expression.Call(propertyExpr,equalsMethod,nullableIntExpr); // This line throws the exception.
Console.WriteLine(result);
}
class myClass{public int? MyProperty{get;set;}}
This line: 这一行:
containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });
returns a MethodInfo
for the method Int32?.Equals (Object other)
. 返回方法Int32?.Equals (Object other)
的MethodInfo
Int32?.Equals (Object other)
。 Notice the parameter type is object
, not Int32
(or Int32?
) as you might expect. 请注意,参数类型是object
,而不是您期望的Int32
(或Int32?
)。
The reason is typeof(Int32?)
is System.Nullable<Int32>
, which only has the Equals(object)
method. 原因是typeof(Int32?)
是System.Nullable<Int32>
,它只有Equals(object)
方法。
Playing around with this in LinqPad, I think the problem is around: 在LinqPad中玩这个,我认为问题在于:
searchExpression = Expression.Constant(_int1);
when you call: 你打电话的时候:
containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });
The Equals
method you're attempting to call is object.Equals(object)
and the compiler is telling you that the type int?
你试图调用的Equals
方法是object.Equals(object)
,编译器告诉你int?
类型int?
is not the type object
that the method expects. 不是该方法所期望的类型object
。
The simplest fix (though I'm not sure that the overall code will work, though this particular error will go away) is to change the overload of the Expression.Constant
that you call to one that specifies the type that Equals
expects: 最简单的修复(虽然我不确定整个代码是否可行,但这个特殊错误会消失)是改变您调用的Expression.Constant
的重载,指定Equals
期望的类型:
searchExpression = Expression.Constant(_int1, typeof(object));
This will compile- however, there's a few things to note. 这将编译 - 但是,有一些事情需要注意。
Your original Expression.Constant(_int1)
results in a ConstantExpression
with Type
int
not int?
你原来的Expression.Constant(_int1)
导致一个ConstantExpression
其中Type
int
不是int?
. 。 You'd need to specify the nullable type, if you needed that ( Expression.Constant(_int1, typeof(int?))
). 如果需要,您需要指定可空类型( Expression.Constant(_int1, typeof(int?))
)。 However, you'll need to cast it to object
anyway, as above. 但是,如上所述,您还需要将其转换为object
。
Specifying containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });
指定containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });
shouldn't work anyway, as there's not such method int?.Equals(int?)
, the Equals
method is the override of the method on the System.Object
class which takes an object
parameter and is the root of the problem. 无论如何都不应该工作,因为没有这样的方法int?.Equals(int?)
, Equals
方法是System.Object
类上的方法的重写,它接受一个object
参数并且是问题的根。 You may as well use: typeof(object).GetMethod("Equals", new[] { typeof(object) });
您也可以使用: typeof(object).GetMethod("Equals", new[] { typeof(object) });
as that's the correct declaration. 因为这是正确的声明。
As I said, it should compile with object
, whether the code does what you expect, I'm not sure, but I think so. 正如我所说,它应该与object
编译,代码是否符合你的期望,我不确定,但我想是的。 I look forward to seeing whether it works :) 我期待看到它是否有效:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.