Выражение типа «System.Int32» не может использоваться для параметра типа «System.Object» метода «Boolean Equals (System.Object)»

я столкнулся с одной ошибкой, работая с функцией поиска по столбцу с сеткой. здесь у меня есть несколько столбцов с varchar, int и nullable. я делаю один вспомогательный метод, такой как FilterColumn, который принимает два аргумента (ColumnName, SearchText). теперь я столкнулся с одной проблемой при фильтрации с помощью значений int.

вот этот метод:

public static class Helper
{
    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;
            Expression converted = null;
            switch (colName)
            {
                // section for int properties
                case "party_id":
                case "type_id":
                case "status_id":
                case "category_id":  //here problem occurs
                    Int32 _int = Convert.ToInt32(searchText);
                    searchExpression = Expression.Constant(_int);
                    containsMethod = typeof(Int32).GetMethod("Equals", new[] { typeof(Int32) });
                    body = Expression.Call(propertyExpression, containsMethod, searchExpression);
                    break;
                // section for int? properties
                case "country_id":
                case "state_id":
                    Int32? _int1 = Convert.ToInt32(searchText);
                    searchExpression = Expression.Constant(_int1);
                    converted = Expression.Convert(searchExpression, typeof(object));
                    containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });
                    body = Expression.Call(propertyExpression, containsMethod, converted);
                    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_date":
                case "Register_Date":
                    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;
        }
    }
}

и вот мой код кнопки поиска, как я передаю значение столбца и значения поиска в FillGrid:

protected void btnsearch_Click(object sender, System.EventArgs e)
    {
        if (DDL_Column_List.SelectedItem.Value.Equals("19"))
        {
            RegularExpressionValidator5.Enabled = true;
        }
      if (Page.IsValid)
        {
            using (DataClassesDataContext db = new DataClassesDataContext())
            {
                System.Threading.Thread.Sleep(2000);
                if (DDL_Column_List.SelectedItem.Value != "-1" && txtsearch.Text.Trim() != "")
                {
                    switch (DDL_Column_List.SelectedItem.Text.ToString())
                    {
                        case "Name":
                            Session["ColumnName"] = "Name";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Type":
                            Session["ColumnName"] = "type_id";
                            Session["SearchText"] = db.PartyTypes.Where(t => t.typename.Contains(txtsearch.Text.Trim())).Select(t => t.Id).SingleOrDefault().ToString();
                            break;
                        case "Owner Name":
                            Session["ColumnName"] = "Ownername";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Owner Mobile":
                            Session["ColumnName"] = "Ownermob";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Contact Person Name":
                            Session["ColumnName"] = "ContactPerson";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Contact Person Mobile":
                            Session["ColumnName"] = "ContactPersonmob";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Phone":
                            Session["ColumnName"] = "Phone";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Mobile":
                            Session["ColumnName"] = "Mobile";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Room":
                            Session["ColumnName"] = "Room";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Building":
                            Session["ColumnName"] = "Build";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Road":
                            Session["ColumnName"] = "Road";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Area":
                            Session["ColumnName"] = "Area";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "City":
                            Session["ColumnName"] = "City";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Country":
                            Session["ColumnName"] = "country_id";
                            Session["SearchText"] = db.Countries.Where(c => c.Country_name.Equals(txtsearch.Text.Trim())).Select(c => c.Id).SingleOrDefault().ToString();
                            break;
                        case "State":
                            Session["ColumnName"] = "state_id";
                            Session["SearchText"] = db.States.Where(s => s.state_name.Equals(txtsearch.Text.Trim())).Select(s => s.Id).SingleOrDefault().ToString();
                            break;
                        case "Email":
                            Session["ColumnName"] = "Email";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Remark":
                            Session["ColumnName"] = "Remark";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Username":
                            Session["ColumnName"] = "Username";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                        case "Register Date":
                            Session["ColumnName"] = "Register_Date";
                            Session["SearchText"] = txtsearch.Text.Trim();
                            break;
                    }
                }
                else
                {
                    Session["SearchText"] = null;
                    Session["ColumnName"] = null;
                }
                this.FillGrid((String)Session["StartAlpha"] ?? null, (int)Session["GroupByENTYPE"] , (String)Session["ColumnName"] ?? null, (String)Session["SearchText"] ?? null);
                UpdatePanel10.Update();
                MPE.Show();
            }
        }
    }

здесь я столкнулся с одной проблемой при работе со значением int, когда пользователь вводит некоторые строковые значения, такие как «Клиент», тогда мне нужно выяснить, какой идентификатор принадлежит этому тексту, и я передаю этот идентификатор в сеанс, а затем мой вспомогательный метод фильтрует его. теперь у меня проблема с type_id. здесь одна ошибка, например:

Server Error in '/CRM' Application.

Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' of method 'Boolean Equals(System.Object)'

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.ArgumentException: Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' of method 'Boolean Equals(System.Object)'

Source Error: 


Line 42:                     converted = Expression.Convert(searchExpression, typeof(object));
Line 43:                     containsMethod = typeof(Int32).GetMethod("Equals", new[] { typeof(Int32) });
Line 44:                     body = Expression.Call(propertyExpression, containsMethod, searchExpression);
Line 45:                     break;
Line 46:                 case "country_id":

Source File: f:\CRM\App_Code\Helper.cs    Line: 44 

Stack Trace: 


[ArgumentException: Expression of type 'System.Int32' cannot be used for parameter of type 'System.Object' of method 'Boolean Equals(System.Object)']
   System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi) +4189655
   System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ReadOnlyCollection`1& arguments) +132
   System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments) +71
   System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression[] arguments) +29
   Helper.FilterForColumn(IQueryable`1 queryable, String colName, String searchText) in f:\CRM\App_Code\Helper.cs:44
   Staff_Raise_Ticket.FillGrid(String StartAlpha, Int32 GroupByENTYPE, String ColumnName, String SearchText) in f:\CRM\Staff\Raise_Ticket.aspx.cs:249
   Staff_Raise_Ticket.btnsearch_Click(Object sender, EventArgs e) in f:\CRM\Staff\Raise_Ticket.aspx.cs:1342
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1

и я не понимаю что тут не так....


person Shal    schedule 12.05.2014    source источник
comment
это довольно просто. Вы передаете int вместо system.object. Тщательно проверьте свой код   -  person qamar    schedule 12.05.2014
comment
в случае: state_id, вы пытаетесь назначить обнуляемый Int32, используя Convert.ToInt32, который всегда будет возвращать 32-битное целое число со знаком. Вы можете предвидеть это с помощью int t; _int = Int32.TryParse(searchText, out t)? (инт?) т : ноль;   -  person Wim Ombelets    schedule 12.05.2014


Ответы (1)


Код в вашей ошибке не соответствует коду вашего Helper метода. Ошибка сообщает об этом:

    converted = Expression.Convert(searchExpression, typeof(object));
    containsMethod = typeof(Int32).GetMethod("Equals", new[] { typeof(Int32) });
    body = Expression.Call(propertyExpression, containsMethod, searchExpression);
    break;
case "country_id":

Когда я ищу ваш код для case "country_id":, я нахожу эти строки:

case "category_id":  //here problem occurs
    Int32 _int = Convert.ToInt32(searchText);
    searchExpression = Expression.Constant(_int);
    containsMethod = typeof(Int32).GetMethod("Equals", new[] { typeof(Int32) });
    body = Expression.Call(propertyExpression, containsMethod, searchExpression);
    break;
// section for int? properties
case "country_id":

Первая строка кода, указанная в ошибке

converted = Expression.Convert(searchExpression, typeof(object));

не появляется в опубликованном вами коде и, вероятно, является источником ошибки: вы пытаетесь вызвать метод, который ожидает параметр Int32 с параметром object, потому что вы конвертируете searchExpression (который, вероятно, уже имеет правильный тип, Int32) для ввода object. Убедитесь, что код, на который вы смотрите, является исполняемым кодом, и удалите преобразование в объект.

person Rik    schedule 12.05.2014