简体   繁体   English

类型'System.Int32'的表达式不能用于方法'Boolean Equals(System.Object)'的'System.Object'类型的参数

[英]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. 这将编译 - 但是,有一些事情需要注意。

  1. 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

  2. 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.

相关问题 类型&#39;System.Int32&#39;的表达式不能用于方法&#39;Boolean Equals(System.Object)&#39;的类型&#39;System.Object&#39;的参数 - Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' of method 'Boolean Equals(System.Object)' Linq和Equality Operator:类型'System.Int32'的表达式不能用于'System.Object'类型的参数 - Linq and the Equality Operator: Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' 类型'System.Int32'的表达式不能用于返回类型'System.Object' - Expression of type 'System.Int32' cannot be used for return type 'System.Object' 从字符串构建 Linq 排序表达式会导致“Expression of "system.int32" can not be used for return type "System.Object"” - Building a Linq sort expression from string results in 'Expression of "system.int32" can not be used for return type "System.Object" ' &#39;System.Int16&#39;类型的表达式不能用于返回类型&#39;System.Object&#39; - Expression of type 'System.Int16' cannot be used for return type 'System.Object' “System.Int64”类型的表达式不能用于返回类型“System.Object” - Expression of type 'System.Int64' cannot be used for return type 'System.Object' 无法将类型为“WhereListIterator`1[System.Object]”的对象转换为类型“System.Collections.Generic.IEnumerable`1[System.Int32]” - Unable to cast object of type 'WhereListIterator`1[System.Object]' to type 'System.Collections.Generic.IEnumerable`1[System.Int32]' Asp.net WebService 无法将“System.Int32”类型的 object 转换为 ty...neric.IDictionary`2[System.String,System.Object]' - Asp.net WebService Cannot convert object of type 'System.Int32' to ty…neric.IDictionary`2[System.String,System.Object]' 无法将类型“ System.Int32”强制转换为类型“ System.Object”。 LINQ to Entities仅支持强制转换EDM基本类型或枚举类型 - Unable to cast the type 'System.Int32' to type'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types &#39;System.DateTime&#39;类型的表达式不能用于返回类型&#39;System.Object&#39; - Expression of type 'System.DateTime' cannot be used for return type 'System.Object'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM