using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace wispro.sp.share { [Serializable] public class ExpressTree { private ConditionTreeNode root ; public void AddCondition(LogicEnum logic, FieldCondition fieldCondition) { FieldConditionNode rightNode = new FieldConditionNode() { FieldCondition = fieldCondition }; if (root == null) { Console.WriteLine("根节点为空时添加!"); root = rightNode; } else { Console.WriteLine("根节点为空时添加!"); OperateNode root1 = new OperateNode() { Operator = logic }; Console.WriteLine("\t设定右节点!"); root1.Right = rightNode; Console.WriteLine("\t设定左节点!"); root1.Left = root; Console.WriteLine("\t设定根节点为操作节点!"); root = root1; Console.WriteLine((root != null)?"\t根节点不为空": "\t根节点为空"); } //Console.WriteLine($"表达式: {ToExpressString("s")}"); } public string ToExpressString(string prefix) { if(root == null) { return null; } else { if(root is FieldConditionNode) { return ((FieldConditionNode)root).FieldCondition.ToExpressString(prefix); } else { OperateNode operate = (OperateNode)root; if(root.Right != null && root.Left != null) { ExpressTree leftTree = new ExpressTree() { root = root.Left }; ExpressTree rightTree = new ExpressTree() { root = root.Right }; switch (operate.Operator) { case LogicEnum.And: return $"({leftTree.ToExpressString(prefix)}) && ({rightTree.ToExpressString(prefix)})"; break; case LogicEnum.Or: return $"({leftTree.ToExpressString(prefix)}) || ({rightTree.ToExpressString(prefix)})"; break; default: return ""; } } else { throw (new ApplicationException("无效的表达是树!")); } } } } } [Serializable] public class ConditionTreeNode { public ConditionTreeNode Right { get; set; } public ConditionTreeNode Left { get; set; } } [Serializable] public class OperateNode : ConditionTreeNode { public LogicEnum Operator { get; set; } } [Serializable] public class FieldConditionNode : ConditionTreeNode { public FieldCondition FieldCondition { get; set; } } [Serializable] public class OrderField { /// /// 排序栏位 /// public string FieldName { get; set; } /// /// 排序 0:顺序;1:倒序 /// public int Sort { get; set; } } [Serializable] public class FieldCondition { /// /// 字段名称 /// public string FieldName { get; set; } /// /// 值 /// public string Value { get; set; } /// /// 值类型 /// public string ValueType { get; set; } /// /// /// public OperatorEnum Operator { get; set; } public LogicEnum LogicOperate { get; set; } public string ToExpressString(string prefix) { bool isString = (ValueType == typeof(string).ToString()); switch (Operator) { case OperatorEnum.Contains: if (isString) { return $"{prefix}.{FieldName}.Contains(\"{Value.Trim()}\")"; } else { throw (new ApplicationException("Contains 操作只对字符字段有效!")); } break; case OperatorEnum.NotContains: if (isString) { return $"!{prefix}.{FieldName}.Contains(\"{Value}\")"; } else { throw (new ApplicationException("Contains 操作只对字符字段有效!")); } break; case OperatorEnum.Equal: if (isString) { return $"{prefix}.{FieldName} == (\"{Value}\")"; } else { return $"{prefix}.{FieldName} == ({Value})"; } break; case OperatorEnum.NotEqual: if (isString) { return $"{prefix}.{FieldName} != (\"{Value}\")"; } else { return $"{prefix}.{FieldName} != ({Value})"; } break; case OperatorEnum.Greater: if (isString) { return $"{prefix}.{FieldName} > (\"{Value}\")"; } else { return $"{prefix}.{FieldName} > ({Value})"; } break; case OperatorEnum.GreaterEqual: if (isString) { return $"{prefix}.{FieldName} >= (\"{Value}\")"; } else { return $"{prefix}.{FieldName} >= ({Value})"; } break; case OperatorEnum.Less : if (isString) { return $"{prefix}.{FieldName} < (\"{Value}\")"; } else { return $"{prefix}.{FieldName} < ({Value})"; } break; case OperatorEnum.LessEqual: if (isString) { return $"{prefix}.{FieldName} <= (\"{Value}\")"; } else { return $"{prefix}.{FieldName} <= ({Value})"; } break; case OperatorEnum.StartsWith: if (isString) { return $"{prefix}.{FieldName}.StartsWith(\"{Value}\")"; } else { throw (new ApplicationException("StartsWith 操作只对字符字段有效!")); } break; case OperatorEnum.EndWith: if (isString) { return $"{prefix}.{FieldName}.EndWith(\"{Value}\")"; } else { throw (new ApplicationException("EndWith 操作只对字符字段有效!")); } break; //case OperatorEnum.In: // break; //case OperatorEnum.Between: // break; default: throw (new ApplicationException("还未实现的操作符号!")); } } } [Serializable] public enum OperatorEnum { Contains, Equal, Greater, GreaterEqual, Less, LessEqual, NotEqual, In, Between, StartsWith, EndWith, NotContains } [Serializable] public enum LogicEnum { And, Or } public static class EFCoreExt { public static IQueryable OrderConditions(this IQueryable query, IList orderConditions) { foreach (var orderinfo in orderConditions) { var parameter = Expression.Parameter(typeof(T)); var prop = Expression.PropertyOrField(parameter, orderinfo.FieldName); var sortLambda = Expression.Lambda(prop, parameter); Expression>> sortMethod = (() => query.OrderBy(k => null)); if(orderinfo.Sort == 1) { sortMethod = (() => query.OrderByDescending(k => null)); } var methodCallExpression = (sortMethod.Body as MethodCallExpression); if (methodCallExpression == null) throw new Exception("Oops"); var method = methodCallExpression.Method.GetGenericMethodDefinition(); var genericSortMethod = method.MakeGenericMethod(typeof(T), prop.Type); query = (IQueryable)genericSortMethod.Invoke(query, new object[] { query, sortLambda }); } return query; } public static IOrderedQueryable SortMeDynamically( this IQueryable query, string propertyname) { var param = Expression.Parameter(typeof(TEntityType), "s"); var prop = Expression.PropertyOrField(param, propertyname); var sortLambda = Expression.Lambda(prop, param); Expression>> sortMethod = (() => query.OrderBy(k => null)); var methodCallExpression = (sortMethod.Body as MethodCallExpression); if (methodCallExpression == null) throw new Exception("Oops"); var method = methodCallExpression.Method.GetGenericMethodDefinition(); var genericSortMethod = method.MakeGenericMethod(typeof(TEntityType), prop.Type); var orderedQuery = (IOrderedQueryable)genericSortMethod.Invoke(query, new object[] { query, sortLambda }); return orderedQuery; } public static IQueryable Pager(this IQueryable query, int pageindex, int pagesize, out int itemCount) { itemCount = query.Count(); return query.Skip((pageindex - 1) * pagesize).Take(pagesize); } } }