Прежде всего, извините за мой плохой английский, это не мой родной язык.
Я использую jqgrid в проекте ASP.NET MVC на моей работе, и у меня есть некоторые проблемы при реализации поиска.Я пытаюсь использовать одно решение, которое найти в Интернете, используя LinqExtensions.Проблема возникает, когда сущность имеет значение NULL, например:
public class MyClass()
{
string StringValue { get; set; }
int? IntegerValue { get; set; }
}
. Это связано с тем, что в базе данных значения принимают значение NULL, и для других целей проекта требуются значения NULL.
В другом классе с именем LinqExtensions предложение where выглядит следующим образом:
public static IQueryable<T> Where<T>(this IQueryable<T> source, string searchProperty, string searchString, string searchOper)
{
Type type = typeof(T);
if (string.IsNullOrEmpty(searchString))
return source;
ConstantExpression searchFilter = Expression.Constant(searchString.ToUpper());
ParameterExpression parameter = Expression.Parameter(type, "p");
//PropertyInfo property = type.GetProperty(searchProperty);
//Expression propertyAccess = Expression.MakeMemberAccess(parameter, property);
MemberExpression memberAccess = null;
String[] separador = {"__"};
foreach (var property2 in searchProperty.Split(separador, StringSplitOptions.None))
memberAccess = MemberExpression.Property
(memberAccess ?? (parameter as Expression), property2);
Expression propertyAccess = memberAccess;
if (propertyAccess.Type == typeof(Nullable<DateTime>))
{
PropertyInfo valProp = typeof(Nullable<DateTime>).GetProperty("Value");
propertyAccess = Expression.MakeMemberAccess(propertyAccess, valProp);
Nullable<DateTime> tn = DateTime.Parse(searchString);
searchFilter = Expression.Constant(tn);
}
//support int?
if (propertyAccess.Type == typeof(Nullable<Char>))
{
PropertyInfo valProp = typeof(Nullable<Char>).GetProperty("Value");
propertyAccess = Expression.MakeMemberAccess(propertyAccess, valProp);
Nullable<Char> tn = Char.Parse(searchString);
searchFilter = Expression.Constant(tn);
}
if (propertyAccess.Type == typeof(Nullable<Int16>))
{
PropertyInfo valProp = typeof(Nullable<Int16>).GetProperty("Value");
propertyAccess = Expression.MakeMemberAccess(propertyAccess, valProp);
Nullable<Int16> tn = Int16.Parse(searchString);
searchFilter = Expression.Constant(tn);
}
if (propertyAccess.Type == typeof(Nullable<Int32>))
{
PropertyInfo valProp = typeof(Nullable<Int32>).GetProperty("Value");
propertyAccess = Expression.MakeMemberAccess(propertyAccess, valProp);
Nullable<Int32> tn = Int32.Parse(searchString);
searchFilter = Expression.Constant(tn);
}
if (propertyAccess.Type == typeof(Nullable<Int64>))
{
PropertyInfo valProp = typeof(Nullable<Int64>).GetProperty("Value");
propertyAccess = Expression.MakeMemberAccess(propertyAccess, valProp);
Nullable<Int64> tn = Int64.Parse(searchString);
searchFilter = Expression.Constant(tn);
}
//support decimal?
if (propertyAccess.Type == typeof(Nullable<decimal>))
{
PropertyInfo valProp = typeof(Nullable<decimal>).GetProperty("Value");
propertyAccess = Expression.MakeMemberAccess(propertyAccess, valProp);
Nullable<decimal> tn = Decimal.Parse(searchString);
searchFilter = Expression.Constant(tn);
}
if (propertyAccess.Type == typeof(Char))
searchFilter = Expression.Constant(Char.Parse(searchString));
if (propertyAccess.Type == typeof(Int16))
searchFilter = Expression.Constant(Int16.Parse(searchString));
if (propertyAccess.Type == typeof(Int32))
searchFilter = Expression.Constant(Int32.Parse(searchString));
if (propertyAccess.Type == typeof(Int64))
searchFilter = Expression.Constant(Int64.Parse(searchString));
if (propertyAccess.Type == typeof(decimal))
searchFilter = Expression.Constant(Decimal.Parse(searchString));
if (propertyAccess.Type == typeof(DateTime))
searchFilter = Expression.Constant(DateTime.Parse(searchString));
MethodInfo startsWith = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
MethodInfo endsWith = typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) });
MethodInfo contains = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
//MethodInfo contains = typeof(Int32Extensions).GetMethod("Contains", new Type[] { typeof(Int64), typeof(Int64) });
Expression operation = null;
switch (searchOper)
{
default:
case "eq":
operation = Expression.Equal(propertyAccess, searchFilter);
break;
case "ne":
operation = Expression.NotEqual(propertyAccess, searchFilter);
break;
case "lt":
operation = Expression.LessThan(propertyAccess, searchFilter);
break;
case "le":
operation = Expression.LessThanOrEqual(propertyAccess, searchFilter);
break;
case "gt":
operation = Expression.GreaterThan(propertyAccess, searchFilter);
break;
case "ge":
operation = Expression.GreaterThanOrEqual(propertyAccess, searchFilter);
break;
case "bw":
operation = Expression.Call(propertyAccess, startsWith, searchFilter);
break;
case "bn":
operation = Expression.Call(propertyAccess, startsWith, searchFilter);
operation = Expression.Not(operation);
break;
case "ew":
operation = Expression.Call(propertyAccess, endsWith, searchFilter);
break;
case "en":
operation = Expression.Call(propertyAccess, endsWith, searchFilter);
operation = Expression.Not(operation);
break;
case "cn":
operation = Expression.Call(propertyAccess, contains, searchFilter);
break;
case "nc":
operation = Expression.Call(propertyAccess, contains, searchFilter);
operation = Expression.Not(operation);
break;
}
var whereExpression = Expression.Lambda(operation, parameter);
var resultExpression = Expression.Call(typeof(Queryable), "Where", new Type[] { source.ElementType }, source.Expression, whereExpression);
return source.Provider.CreateQuery<T>(resultExpression);
}
Метод в классе Model:
public JsonResult GetData(GridSettings grid)
{
if (Session["SomeValue"] != null)
{
var query = (new GridModel()).GetQuery();
//Filters
if (grid.IsSearch && grid.Where != null)
{
//And
if (grid.Where.groupOp == "AND")
foreach (var rule in grid.Where.rules)
query = query.Where<MyClass>(rule.field, rule.data.ToUpper(), rule.op);
else
{
//Or
var temp = (new List<MyClass>()).AsQueryable();
foreach (var rule in grid.Where.rules)
{
var t = query.Where<MyClass>(rule.field, rule.data, rule.op);
temp = temp.Concat<MyClass>(t);
}
//Clean repeat elements
query = temp.Distinct<MyClass>();
}
}
//Order
query = query.OrderBy<MyClass>(grid.SortColumn,
grid.SortOrder);
//Count
var count = query.Count();
//Pager
var data = query.Skip((grid.PageIndex - 1) * grid.PageSize).Take(grid.PageSize).ToArray();
//Convert
var result = new
{
.
.
.
}
}
Я создаю сетку, отображаю значения очень правильно, но... при поиске по строке возникает любая проблема, даже если некоторые значения являются нулевыми, и при попытке поиска по IntegerValue (который поддерживает нулевое значение) и исключения генерируется, когда некоторые значения в сущности равны нулю.Эта проблема превращает меня в сумасшедшего.
Пожалуйста, если у кого-то есть такая же проблема или знаете, как ее решить, я буду вечно благодарен
Пока