Выражение типа ' System.Int32 'нельзя использовать для параметра типа' System.Объект "метода" Boolean Equals (System.Объект')
у меня есть один общий метод фильтра столбцов представления сетки, который фильтрует запись представления сетки с помощью ColumnName и SearchText. здесь, когда я работаю с nullable int datacolumn, из этого метода возникает ошибка:
выражение типа ' System.Int32 'нельзя использовать для параметра типа' System.Объект "метода" Boolean Equals (System.Объект)'
мой метод код :
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;
}
}
вот мой запрос, который я уволен :
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();
здесь я включаю свой запрос.метод 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]]
2 ответов
редактировать
нашел решение в этот вопрос. Вам нужно преобразовать выражение в Object
перед вызовом Equals(object)
способ:
var converted = Expression.Convert(searchExpression, typeof(object));
body = Expression.Call(propertyExpression, containsMethod, converted);
Nicodemus13предложение явно установить searchExpression
'ы типа Object
в первую очередь должен работать тоже.
Оригинал
я еще не нашел проблему, но я воспроизвел проблему в SSCCE, используя Помощью 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;}}
эта строка:
containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });
возвращает MethodInfo
для метода Int32?.Equals (Object other)
. Обратите внимание, что тип параметра object
, а не Int32
(или Int32?
) как и следовало ожидать.
причина typeof(Int32?)
и System.Nullable<Int32>
, которая имеет Equals(object)
метод.
играя с этим в LinqPad, я думаю, что проблема вокруг:
searchExpression = Expression.Constant(_int1);
когда вы называете:
containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });
на Equals
метод, который вы пытаетесь назвать это object.Equals(object)
и компилятор говорит вам, что типа int?
не типа object
что метод ожидает.
самое простое исправление (хотя я не уверен, что общий код будет работать, хотя эта конкретная ошибка исчезнет) - это изменить перегрузка Expression.Constant
что вы вызываете к одному, который указывает тип, который Equals
ожидает:
searchExpression = Expression.Constant(_int1, typeof(object));
это компиляции, однако, есть несколько вещей, чтобы отметить.
ваш оригинальный
Expression.Constant(_int1)
результатыConstantExpression
СType
int
неint?
. Вам нужно будет указать тип nullable, если вам это нужно (Expression.Constant(_int1, typeof(int?))
). Тем не менее, вам нужно будет бросить его вobject
в любом случае, как выше.задание
containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });
не должен работать в любом случае, так как нет такого методаint?.Equals(int?)
, theEquals
метод переопределить метод наSystem.Object
класс, который берет