/// <summary> /// 验证排序与查询字段合法性 /// </summary> /// <param name="options"></param> /// <param name="queryable"></param> /// <returns></returns> private PageDataOptions ValidatePageOptions(PageDataOptions options, out IQueryable <T> queryable) { options = options ?? new PageDataOptions(); GetPageDataSort(options, TProperties); List <SearchParameters> searchParametersList = new List <SearchParameters>(); if (!string.IsNullOrEmpty(options.Wheres)) { try { searchParametersList = options.Wheres.DeserializeObject <List <SearchParameters> >(); } catch { } } QueryRelativeList?.Invoke(searchParametersList); // Connection queryable = repository.DbContext.Set <T>(); //判断列的数据类型数字,日期的需要判断值的格式是否正确 for (int i = 0; i < searchParametersList.Count; i++) { SearchParameters x = searchParametersList[i]; x.DisplayType = x.DisplayType.GetDBCondition(); if (string.IsNullOrEmpty(x.Value)) { searchParametersList.Remove(x); continue; } PropertyInfo property = TProperties.Where(c => c.Name.ToUpper() == x.Name.ToUpper()).FirstOrDefault(); // property //移除查询的值与数据库类型不匹配的数据 // x.Value = string.Join(",", dbType.ValidationVal(x.Value.Split(',')).Where(q => q != "")); object[] values = property.ValidationValueForDbType(x.Value.Split(',')).Where(q => q.Item1).Select(s => s.Item3).ToArray(); // if (string.IsNullOrEmpty(x.Value)) if (values == null || values.Length == 0) { searchParametersList.Remove(x); continue; } if (x.DisplayType == HtmlElementType.Contains) { x.Value = string.Join(",", values); } LinqExpressionType expressionType = x.DisplayType.GetLinqCondition(); queryable = LinqExpressionType.In == expressionType ? queryable.Where(x.Name.CreateExpression <T>(values, expressionType)) : queryable.Where(x.Name.CreateExpression <T>(x.Value, expressionType)); } options.Wheres = searchParametersList.GetEntitySql(); options.TableName = base.TableName ?? typeof(T).Name; return(options); }
/// <summary> /// 验证排序与查询字段合法性 /// </summary> /// <param name="options"></param> /// <param name="queryable"></param> /// <returns></returns> private PageDataOptions ValidatePageOptions(PageDataOptions options, out IQueryable <Hiiops_Cart> queryable, List <SearchParameters> searchParametersList) { options = options ?? new PageDataOptions(); queryable = Instance.DbContext.Set <Hiiops_Cart>(); //判断列的数据类型数字,日期的需要判断值的格式是否正确 for (int i = 0; i < searchParametersList.Count; i++) { SearchParameters x = searchParametersList[i]; x.DisplayType = x.DisplayType.GetDBCondition(); if (string.IsNullOrEmpty(x.Value)) { // searchParametersList.Remove(x); continue; } PropertyInfo property = TProperties.Where(c => c.Name.ToUpper() == x.Name.ToUpper()).FirstOrDefault(); // property //移除查询的值与数据库类型不匹配的数据 // x.Value = string.Join(",", dbType.ValidationVal(x.Value.Split(',')).Where(q => q != "")); object[] values = property.ValidationValueForDbType(x.Value.Split(',')).Where(q => q.Item1).Select(s => s.Item3).ToArray(); // if (string.IsNullOrEmpty(x.Value)) if (values == null || values.Length == 0) { // searchParametersList.Remove(x); continue; } if (x.DisplayType == HtmlElementType.Contains) { x.Value = string.Join(",", values); } LinqExpressionType expressionType = x.DisplayType.GetLinqCondition(); queryable = LinqExpressionType.In == expressionType ? queryable.Where(x.Name.CreateExpression <Hiiops_Cart>(values, expressionType)) : queryable.Where(x.Name.CreateExpression <Hiiops_Cart>(x.Value, expressionType)); } // options.Wheres = searchParametersList.GetEntitySql(); return(options); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="propertyName">字段名</param> /// <param name="propertyValue">表达式的值</param> /// <param name="expressionType">创建表达式的类型,如:p=>p.propertyName != propertyValue /// p=>p.propertyName.Contains(propertyValue)</param> /// <returns></returns> private static Expression <Func <T, bool> > CreateExpression <T>(this string propertyName, object propertyValue, ParameterExpression parameter, LinqExpressionType expressionType) { Expression <Func <T, bool> > expression; Type proType = typeof(T).GetProperty(propertyName).PropertyType; //创建节点变量如p=>的节点p parameter = parameter ?? Expression.Parameter(typeof(T), "p");//创建参数p //创建节点的属性p=>p.name 属性name MemberExpression memberProperty = Expression.PropertyOrField(parameter, propertyName); if (expressionType == LinqExpressionType.In) { System.Collections.IList list = propertyValue as System.Collections.IList; if (list == null || list.Count == 0) { throw new Exception("属性值类型不正确"); } List <object> objList = new List <object>(); bool isString = true; if (proType.ToString() != "System.String") { foreach (var item in list) { objList.Add(item.ToString().ChangeType(proType)); } list = objList; isString = false; } //typeof(List<string>) MethodInfo method = typeof(System.Collections.IList).GetMethod("Contains"); //创建集合常量并设置为常量的值 ConstantExpression constantCollection = Expression.Constant(list); //创建一个表示调用带参数的方法的:new string[]{"1","a"}.Contains("a"); MethodCallExpression methodCall = null; if (isString) { methodCall = Expression.Call(constantCollection, method, memberProperty); } else { methodCall = Expression.Call(constantCollection, method, Expression.Convert(memberProperty, typeof(object))); } //Expression.Convert( //创建委托p=>new string[]{"1","a"}.Contains(p.name); expression = Expression.Lambda <Func <T, bool> >(methodCall, parameter); return(expression); } // object value = propertyValue; ConstantExpression constant = proType.ToString() == "System.String" ? Expression.Constant(propertyValue) : Expression.Constant(propertyValue.ToString().ChangeType(proType)); UnaryExpression member = Expression.Convert(memberProperty, constant.Type); switch (expressionType) { //p=>p.propertyName == propertyValue case LinqExpressionType.Equal: expression = Expression.Lambda <Func <T, bool> >(Expression.Equal(member, constant), parameter); break; //p=>p.propertyName != propertyValue case LinqExpressionType.NotEqual: expression = Expression.Lambda <Func <T, bool> >(Expression.NotEqual(member, constant), parameter); break; // p => p.propertyName > propertyValue case LinqExpressionType.GreaterThan: expression = Expression.Lambda <Func <T, bool> >(Expression.GreaterThan(member, constant), parameter); break; // p => p.propertyName < propertyValue case LinqExpressionType.LessThan: expression = Expression.Lambda <Func <T, bool> >(Expression.LessThan(member, constant), parameter); break; // p => p.propertyName >= propertyValue case LinqExpressionType.ThanOrEqual: expression = Expression.Lambda <Func <T, bool> >(Expression.GreaterThanOrEqual(member, constant), parameter); break; // p => p.propertyName <= propertyValue case LinqExpressionType.LessThanOrEqual: expression = Expression.Lambda <Func <T, bool> >(Expression.LessThanOrEqual(member, constant), parameter); break; // p => p.propertyName.Contains(propertyValue) // p => !p.propertyName.Contains(propertyValue) case LinqExpressionType.Contains: case LinqExpressionType.NotContains: MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); constant = Expression.Constant(propertyValue, typeof(string)); if (expressionType == LinqExpressionType.Contains) { expression = Expression.Lambda <Func <T, bool> >(Expression.Call(member, method, constant), parameter); } else { expression = Expression.Lambda <Func <T, bool> >(Expression.Not(Expression.Call(member, method, constant)), parameter); } break; default: // p => p.false expression = False <T>(); break; } return(expression); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="propertyName">字段名</param> /// <param name="propertyValue">表达式的值</param> /// <param name="expressionType">创建表达式的类型,如:p=>p.propertyName != propertyValue /// p=>p.propertyName.Contains(propertyValue)</param> /// <returns></returns> public static Expression <Func <T, bool> > CreateExpression <T>(this string propertyName, object propertyValue, LinqExpressionType expressionType) { return(propertyName.CreateExpression <T>(propertyValue, null, expressionType)); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="propertyName">字段名</param> /// <param name="propertyValue">表达式的值</param> /// <param name="expressionType">创建表达式的类型,如:p=>p.propertyName != propertyValue /// p=>p.propertyName.Contains(propertyValue)</param> /// <returns></returns> private static Expression <Func <T, bool> > CreateExpression <T>( this string propertyName, object propertyValue, ParameterExpression parameter, LinqExpressionType expressionType) { Type proType = typeof(T).GetProperty(propertyName).PropertyType; //创建节点变量如p=>的节点p // parameter ??= Expression.Parameter(typeof(T), "p");//创建参数p parameter = parameter ?? Expression.Parameter(typeof(T), "p"); //创建节点的属性p=>p.name 属性name MemberExpression memberProperty = Expression.PropertyOrField(parameter, propertyName); if (expressionType == LinqExpressionType.In) { if (!(propertyValue is System.Collections.IList list) || list.Count == 0) { throw new Exception("属性值类型不正确"); } bool isStringValue = true; List <object> objList = new List <object>(); if (proType.ToString() != "System.String") { isStringValue = false; foreach (var value in list) { objList.Add(value.ToString().ChangeType(proType)); } list = objList; } if (isStringValue) { //string 类型的字段,如果值带有'单引号,EF会默认变成''两个单引号 MethodInfo method = typeof(System.Collections.IList).GetMethod("Contains"); //创建集合常量并设置为常量的值 ConstantExpression constantCollection = Expression.Constant(list); //创建一个表示调用带参数的方法的:new string[]{"1","a"}.Contains("a"); MethodCallExpression methodCall = Expression.Call(constantCollection, method, memberProperty); return(Expression.Lambda <Func <T, bool> >(methodCall, parameter)); } //非string字段,按上面方式处理报异常Null TypeMapping in Sql Tree BinaryExpression body = null; foreach (var value in list) { ConstantExpression constantExpression = Expression.Constant(value); UnaryExpression unaryExpression = Expression.Convert(memberProperty, constantExpression.Type); body = body == null ? Expression.Equal(unaryExpression, constantExpression) : Expression.OrElse(body, Expression.Equal(unaryExpression, constantExpression)); } return(Expression.Lambda <Func <T, bool> >(body, parameter)); } // object value = propertyValue; ConstantExpression constant = proType.ToString() == "System.String" ? Expression.Constant(propertyValue) : Expression.Constant(propertyValue.ToString().ChangeType(proType)); UnaryExpression member = Expression.Convert(memberProperty, constant.Type); Expression <Func <T, bool> > expression; switch (expressionType) { //p=>p.propertyName == propertyValue case LinqExpressionType.Equal: expression = Expression.Lambda <Func <T, bool> >(Expression.Equal(member, constant), parameter); break; //p=>p.propertyName != propertyValue case LinqExpressionType.NotEqual: expression = Expression.Lambda <Func <T, bool> >(Expression.NotEqual(member, constant), parameter); break; // p => p.propertyName > propertyValue case LinqExpressionType.GreaterThan: expression = Expression.Lambda <Func <T, bool> >(Expression.GreaterThan(member, constant), parameter); break; // p => p.propertyName < propertyValue case LinqExpressionType.LessThan: expression = Expression.Lambda <Func <T, bool> >(Expression.LessThan(member, constant), parameter); break; // p => p.propertyName >= propertyValue case LinqExpressionType.ThanOrEqual: expression = Expression.Lambda <Func <T, bool> >(Expression.GreaterThanOrEqual(member, constant), parameter); break; // p => p.propertyName <= propertyValue case LinqExpressionType.LessThanOrEqual: expression = Expression.Lambda <Func <T, bool> >(Expression.LessThanOrEqual(member, constant), parameter); break; // p => p.propertyName.Contains(propertyValue) // p => !p.propertyName.Contains(propertyValue) case LinqExpressionType.Contains: case LinqExpressionType.NotContains: MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); constant = Expression.Constant(propertyValue, typeof(string)); if (expressionType == LinqExpressionType.Contains) { expression = Expression.Lambda <Func <T, bool> >(Expression.Call(member, method, constant), parameter); } else { expression = Expression.Lambda <Func <T, bool> >(Expression.Not(Expression.Call(member, method, constant)), parameter); } break; default: // p => p.false expression = False <T>(); break; } return(expression); }