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}\")";
}
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);
}
}
}