Jquery jqGrid的LINQ搜索上的可空值
首先,对不起,我的英语不好,这不是我的母语 在我的工作中,我在ASP.NETMVC项目中使用jqgrid,在实现搜索时遇到了一些问题。 我尝试使用一种在互联网上使用LinqExtensions的解决方案。当实体的值为空时会出现问题,如:Jquery jqGrid的LINQ搜索上的可空值,jquery,asp.net-mvc,linq,jqgrid,linq-extensions,Jquery,Asp.net Mvc,Linq,Jqgrid,Linq Extensions,首先,对不起,我的英语不好,这不是我的母语 在我的工作中,我在ASP.NETMVC项目中使用jqgrid,在实现搜索时遇到了一些问题。 我尝试使用一种在互联网上使用LinqExtensions的解决方案。当实体的值为空时会出现问题,如: public class MyClass() { string StringValue { get; set; } int? IntegerValue { get; set; } } 这是因为在数据库中,这些值接受null,并且由于项目上的其他原因
public class MyClass()
{
string StringValue { get; set; }
int? IntegerValue { get; set; }
}
这是因为在数据库中,这些值接受null,并且由于项目上的其他原因,在我的c#code上需要可为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);
}
public static IQueryable Where(此IQueryable源、字符串searchProperty、字符串searchString、字符串searchOper)
{
类型=类型(T);
if(string.IsNullOrEmpty(searchString))
返回源;
ConstantExpression searchFilter=Expression.Constant(searchString.ToUpper());
ParameterExpression参数=表达式参数(类型为“p”);
//PropertyInfo属性=type.GetProperty(searchProperty);
//Expression propertyAccess=Expression.MakeMemberAccess(参数,属性);
MemberExpression memberAccess=null;
字符串[]separador={“\uuu};
foreach(searchProperty.Split(separador、StringSplitOptions.None)中的var property2)
memberAccess=MemberExpression.Property
(memberAccess???(参数作为表达式),property2);
表达式propertyAccess=memberAccess;
if(propertyAccess.Type==typeof(可空))
{
PropertyInfo valProp=typeof(可为空).GetProperty(“值”);
propertyAccess=Expression.MakeMemberAccess(propertyAccess,valProp);
Nullable tn=DateTime.Parse(searchString);
searchFilter=表达式常数(tn);
}
//支持int?
if(propertyAccess.Type==typeof(可空))
{
PropertyInfo valProp=typeof(可为空).GetProperty(“值”);
propertyAccess=Expression.MakeMemberAccess(propertyAccess,valProp);
Nullable tn=Char.Parse(searchString);
searchFilter=表达式常数(tn);
}
if(propertyAccess.Type==typeof(可空))
{
PropertyInfo valProp=typeof(可为空).GetProperty(“值”);
propertyAccess=Expression.MakeMemberAccess(propertyAccess,valProp);
Nullable tn=Int16.Parse(searchString);
searchFilter=表达式常数(tn);
}
if(propertyAccess.Type==typeof(可空))
{
PropertyInfo valProp=typeof(可为空).GetProperty(“值”);
propertyAccess=Expression.MakeMemberAccess(propertyAccess,valProp);
Nullable tn=Int32.Parse(searchString);
searchFilter=表达式常数(tn);
}
if(propertyAccess.Type==typeof(可空))
{
PropertyInfo valProp=typeof(可为空).GetProperty(“值”);
propertyAccess=Expression.MakeMemberAccess(propertyAccess,valProp);
Nullable tn=Int64.Parse(searchString);
searchFilter=表达式常数(tn);
}
//支持十进制吗?
if(propertyAccess.Type==typeof(可空))
{
PropertyInfo valProp=typeof(可为空).GetProperty(“值”);
propertyAccess=Expression.MakeMemberAccess(propertyAccess,valProp);
Nullable tn=Decimal.Parse(searchString);
searchFilter=表达式常数(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(十进制))
searchFilter=Expression.Constant(Decimal.Parse(searchString));
if(propertyAccess.Type==typeof(DateTime))
searchFilter=Expression.Constant(DateTime.Parse(searchString));
MethodInfo startsWith=typeof(string).GetMethod(“startsWith”,新类型[]{typeof(string)});
MethodInfo endsWith=typeof(string).GetMethod(“endsWith”,新类型[]{typeof(string)});
MethodInfo contains=typeof(string).GetMethod(“contains”,新类型[]{typeof(string)});
//MethodInfo contains=typeof(Int32Extensions).GetMethod(“contains”,新类型[]{typeof(Int64),typeof(Int64)});
表达式运算=null;
开关(搜索操作器)
{
违约:
案例“eq”:
操作=表达式.Equal(propertyAccess,searchFilter);
打破
案例“ne”:
operation=Expression.NotEqual(propertyAccess,searchFilter);
打破
案例“lt”:
operation=Expression.LessThan(propertyAccess,searchFilter);
打破
案例“le”:
操作=Expression.lessthanRequal(propertyAccess,searchFilter);
打破
案例“gt”:
operation=Expression.GreaterThan(propertyAccess,searchFilter);
打破
案例“ge”:
operation=Expression.GreaterThanOrEqual(propertyAccess,searchFilter);
打破
案例“bw”:
operation=Expression.Call(propertyAccess、StartWith、searchFilter);
打破
案例“bn”:
operation=Expression.Call(propertyAccess、StartWith、searchFilter);
操作=表达式。非(操作);
打破
“ew”案:
operation=Expression.Call(propertyAccess、endsWith、searchFilt
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
{
.
.
.
}
}
private static Expression LinqEqual(Expression e1, Expression e2)
{
if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
e2 = Expression.Convert(e2, e1.Type);
else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
e1 = Expression.Convert(e1, e2.Type);
return Expression.Equal(e1, e2);
}
private static bool IsNullableType(Type t)
{
return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>);
}
Expression operation = null;
switch (searchOper)
{
default:
case "eq":
operation = Expression.Equal(propertyAccess, searchFilter);
break;
.
.
.
}