我有一个共同的网格视图列过滤器的方法,与的ColumnName和SearchText明智的过滤器网格视图记录。这里的时候,我可为空INT DataColumn的操作存在误差从此方法抛出这样的:
防爆$类型'System.Int32的的对$ pssion不能用于类型参数'System.Object的'法'布尔等于(System.Object的)'
我的方法code是:
公共静态的IQueryable< T> FilterForColumn< T>(这IQueryable的< T>可查询字符串COLNAME,串searchText)
{
如果(COLNAME = NULL和放大器;!&安培;!searchText = NULL)
{
VAR参数=前pression.Parameter(typeof运算(T),M);
VAR propertyEx pression =前pression.Property(参数COLNAME);
System.Linq.Ex pressions.ConstantEx pression searchEx pression = NULL;
System.Reflection.MethodInfo containsMethod = NULL;
//这必须是防爆型$ P $ pssion接受不同类型的EX pressions
//即BinaryEx pression,MethodCallEx pression,...
System.Linq.Ex pressions.Ex pression体= NULL;
防爆pression EX1 = NULL;
防爆pression EX2 = NULL;
开关(COLNAME)
{
案作业ID:
案status_id:
INT32 _INT = Convert.ToInt32(searchText);
searchEx pression =前pression.Constant(_INT);
containsMethod = typeof运算(Int32)已.GetMethod(等于,新的[] {typeof运算(Int32)已});
身体=前pression.Call(propertyEx pression,containsMethod,searchEx pression);
打破;
案GROUP_ID:
INT32? _int1 = Convert.ToInt32(searchText);
searchEx pression =前pression.Constant(_int1);
。containsMethod = typeof运算(?Int32)在GetMethod的(等于,新的[] {typeof运算(Int32)已?});
//错误,从该行抛出
身体=前pression.Call(propertyEx pression,containsMethod,searchEx pression);
打破;
案文件大小:
案TotalFileSize:
Int64的? _int2 = Convert.ToInt64(searchText);
searchEx pression =前pression.Constant(_int2);
。containsMethod = typeof运算(?的Int64)GetMethod的(等于,新的[] {typeof运算(Int64的)?});
身体=前pression.Call(propertyEx pression,containsMethod,searchEx pression);
打破;
//节日期时间?性能
案PublishDate:
案Birth_date:
案Anniversary_date:
案Profile_Updated_datetime:
案CompletedOn:
日期时间的currentdate = DateTime.ParseExact(searchText,DD / MM / YYYY,NULL);
日期时间nextDate = currentDate.AddDays(1);
EX1 =前pression.GreaterThanOrEqual(propertyEx pression,防爆pression.Constant(的currentdate的typeof(DateTime的)));
EX2 =前pression.LessThan(propertyEx pression,防爆pression.Constant(nextDate的typeof(DateTime的)));
身体=前pression.AndAlso(EX1,EX2);
打破;
//节日期时间属性
案Created_datetime:
案Reminder_Date:
案News_date:
案thought_date:
案SubscriptionDateTime:
案Register_datetime:
案CreatedOn:
日期时间currentDate1 = DateTime.ParseExact(searchText,DD / MM / YYYY,NULL);
日期时间nextDate1 = currentDate1.AddDays(1);
EX1 =前pression.GreaterThanOrEqual(propertyEx pression,防爆pression.Constant(currentDate1));
EX2 =前pression.LessThan(propertyEx pression,防爆pression.Constant(nextDate1));
身体=前pression.AndAlso(EX1,EX2);
打破;
默认:
searchEx pression =前pression.Constant(searchText);
containsMethod = typeof运算(字符串).GetMethod(包含,新的[] {typeof运算(字符串)});
身体=前pression.Call(propertyEx pression,containsMethod,searchEx pression);
打破;
}
VAR predicate =前pression.Lambda< Func键< T,布尔>>(身体,新的[] {参数});
返回queryable.Where(predicate);
}
其他
{
返回可查询;
}
}
这是我的查询,我解雇了:
VAR的查询= Helper.GetUsers()式(U =>!u.Id = USER_ID)。.OrderByDescending(U => u.Register_datetime)。选择(U = >新建
{
n = u.Id,
名称= u.First_name ++ u.Last_name,
IsActive = u.IsActive,
IsVerified = u.IsVerified,
用户名= u.Username,
密码= 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()。
在这里,我有我的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]]解决方案
修改
在找到this问题。您需要调用等于之前(对象)
方法转换前pression到对象
:
VAR转换=前pression.Convert(searchEx pression的typeof(对象));
身体=前pression.Call(propertyEx pression,containsMethod,转换);
倪codemus13 的明确设置的建议 searchEx pression
的类型在首位对象
应该工作了。
原
我还没有发现这个问题,但我已经转载使用Linqpad在SSCCE问题:
无效的主要()
{
VAR将myInstance =新MyClass的();
。VAR equalsMethod = typeof运算(?Int32)在GetMethod的(等于,新的[] {typeof运算(Int32)已?});
诠释? nullableInt = 1;
VAR nullableIntExpr = System.Linq.Ex pressions.Ex pression.Constant(nullableInt);
VAR myInstanceExpr = System.Linq.Ex pressions.Ex pression.Constant(将myInstance);
VAR propertyExpr = System.Linq.Ex pressions.Ex pression.Property(myInstanceExpr,myProperty的);
VAR的结果=前pression.Call(propertyExpr,equalsMethod,nullableIntExpr); //这行抛出异常。
Console.WriteLine(结果);
}
MyClass类{公众诠释? {myProperty的获取;设置;}}
这行:
containsMethod = typeof运算(?Int32)在GetMethod的(等于,新的[] {typeof运算(Int32)已?})。
返回的MethodInfo
的方法的Int32?.Equals(对象等)
。注意参数类型为对象
,不是的Int32
(或的Int32?
)如你所期望的。
原因是的typeof(的Int32?)
是 System.Nullable&LT;的Int32&GT;
,其不仅具有等于(对象)
方法。
i have one common grid view column filter method that filter grid view record with ColumnName and SearchText wise. here when i operate on nullable int datacolumn there is error thrown from this method like :
Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' of method 'Boolean Equals(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.
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:
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.
Original
I haven't found the issue yet, but I have reproduced the problem in a SSCCE using Linqpad:
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)
. Notice the parameter type is object
, not Int32
(or Int32?
) as you might expect.
The reason is typeof(Int32?)
is System.Nullable<Int32>
, which only has the Equals(object)
method.