You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
255 lines
9.6 KiB
255 lines
9.6 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
|
|
namespace SqlSugar
|
|
{
|
|
public class ExpressionTool
|
|
{
|
|
public static string GetOperator(ExpressionType expressiontype)
|
|
{
|
|
switch (expressiontype)
|
|
{
|
|
case ExpressionType.And:
|
|
case ExpressionType.AndAlso:
|
|
return "AND";
|
|
|
|
case ExpressionType.Equal:
|
|
return "=";
|
|
|
|
case ExpressionType.GreaterThan:
|
|
return ">";
|
|
|
|
case ExpressionType.GreaterThanOrEqual:
|
|
return ">=";
|
|
|
|
case ExpressionType.LessThan:
|
|
return "<";
|
|
|
|
case ExpressionType.LessThanOrEqual:
|
|
return "<=";
|
|
|
|
case ExpressionType.NotEqual:
|
|
return "<>";
|
|
|
|
case ExpressionType.Or:
|
|
case ExpressionType.OrElse:
|
|
return "OR";
|
|
|
|
case ExpressionType.Add:
|
|
case ExpressionType.AddChecked:
|
|
return "+";
|
|
|
|
case ExpressionType.Subtract:
|
|
case ExpressionType.SubtractChecked:
|
|
return "-";
|
|
|
|
case ExpressionType.Divide:
|
|
return "/";
|
|
|
|
case ExpressionType.Multiply:
|
|
case ExpressionType.MultiplyChecked:
|
|
return "*";
|
|
|
|
case ExpressionType.Coalesce:
|
|
throw new Exception("Expression no support ?? ,Use SqlFunc.IsNull");
|
|
default:
|
|
Check.ThrowNotSupportedException(string.Format(ErrorMessage.OperatorError, expressiontype.ToString()));
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static object GetValue(object value)
|
|
{
|
|
if (value == null) return value;
|
|
var type = value.GetType();
|
|
if (type.IsEnum() && type != typeof(DateType) && type != typeof(JoinType) && type != typeof(OrderByType)) return Convert.ToInt64(value);
|
|
else
|
|
return value;
|
|
}
|
|
|
|
public static bool IsLogicOperator(string operatorValue)
|
|
{
|
|
return operatorValue == "&&" || operatorValue == "||" || operatorValue == "AND" || operatorValue == "OR";
|
|
}
|
|
|
|
public static bool IsLogicOperator(Expression expression)
|
|
{
|
|
return expression.NodeType == ExpressionType.And ||
|
|
expression.NodeType == ExpressionType.AndAlso ||
|
|
expression.NodeType == ExpressionType.Or ||
|
|
expression.NodeType == ExpressionType.OrElse;
|
|
}
|
|
|
|
public static bool IsComparisonOperator(Expression expression)
|
|
{
|
|
return expression.NodeType != ExpressionType.And &&
|
|
expression.NodeType != ExpressionType.AndAlso &&
|
|
expression.NodeType != ExpressionType.Or &&
|
|
expression.NodeType != ExpressionType.OrElse;
|
|
}
|
|
|
|
public static object GetMemberValue(MemberInfo member, Expression expression)
|
|
{
|
|
var rootExpression = expression as MemberExpression;
|
|
var memberInfos = new Stack<MemberInfo>();
|
|
var fieldInfo = member as System.Reflection.FieldInfo;
|
|
object reval = null;
|
|
MemberExpression memberExpr = null;
|
|
while (expression is MemberExpression)
|
|
{
|
|
memberExpr = expression as MemberExpression;
|
|
memberInfos.Push(memberExpr.Member);
|
|
if (memberExpr.Expression == null)
|
|
{
|
|
var isProperty = memberExpr.Member.MemberType == MemberTypes.Property;
|
|
var isField = memberExpr.Member.MemberType == MemberTypes.Field;
|
|
if (isProperty)
|
|
{
|
|
reval = GetPropertyValue(memberExpr);
|
|
}
|
|
else if (isField)
|
|
{
|
|
reval = GetFiledValue(memberExpr);
|
|
}
|
|
}
|
|
if (memberExpr.Expression == null)
|
|
{
|
|
}
|
|
expression = memberExpr.Expression;
|
|
}
|
|
// fetch the root object reference:
|
|
var constExpr = expression as ConstantExpression;
|
|
if (constExpr == null)
|
|
{
|
|
return DynamicInvoke(rootExpression);
|
|
}
|
|
var objReference = constExpr.Value;
|
|
// "ascend" back whence we came from and resolve object references along the way:
|
|
while (memberInfos.Count > 0) // or some other break condition
|
|
{
|
|
var mi = memberInfos.Pop();
|
|
if (mi.MemberType == MemberTypes.Property)
|
|
{
|
|
var objProp = objReference.GetType().GetProperty(mi.Name);
|
|
objReference = objProp == null ? DynamicInvoke(expression, rootExpression == null ? memberExpr : rootExpression) : objProp.GetValue(objReference, null);
|
|
}
|
|
else if (mi.MemberType == MemberTypes.Field)
|
|
{
|
|
var objField = objReference.GetType().GetField(mi.Name);
|
|
objReference = objField == null ? DynamicInvoke(expression, rootExpression == null ? memberExpr : rootExpression) : objField.GetValue(objReference);
|
|
}
|
|
}
|
|
reval = objReference;
|
|
return reval;
|
|
}
|
|
|
|
public static object GetFiledValue(MemberExpression memberExpr)
|
|
{
|
|
if (!(memberExpr.Member is FieldInfo))
|
|
{
|
|
return DynamicInvoke(memberExpr);
|
|
}
|
|
object reval = null;
|
|
var field = (FieldInfo)memberExpr.Member;
|
|
Check.Exception(field.IsPrivate, $" Field \"{field.Name}\" can't be private ");
|
|
reval = field.GetValue(memberExpr.Member);
|
|
if (reval != null && reval.GetType().IsClass() && reval.GetType() != UtilConstants.StringType)
|
|
{
|
|
var fieldName = memberExpr.Member.Name;
|
|
var proInfo = reval.GetType().GetProperty(fieldName);
|
|
if (proInfo != null)
|
|
{
|
|
reval = proInfo.GetValue(reval, null);
|
|
}
|
|
var fieInfo = reval.GetType().GetField(fieldName);
|
|
if (fieInfo != null)
|
|
{
|
|
reval = fieInfo.GetValue(reval);
|
|
}
|
|
if (fieInfo == null && proInfo == null)
|
|
{
|
|
Check.Exception(field.IsPrivate, $" Field \"{field.Name}\" can't be private ");
|
|
}
|
|
}
|
|
return reval;
|
|
}
|
|
|
|
public static bool IsConstExpression(MemberExpression memberExpr)
|
|
{
|
|
var result = false;
|
|
while (memberExpr != null && memberExpr.Expression != null)
|
|
{
|
|
var isConst = memberExpr.Expression is ConstantExpression;
|
|
if (isConst)
|
|
{
|
|
result = true;
|
|
break;
|
|
}
|
|
memberExpr = memberExpr.Expression as MemberExpression;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static object GetPropertyValue(MemberExpression memberExpr)
|
|
{
|
|
if (!(memberExpr.Member is PropertyInfo))
|
|
{
|
|
return DynamicInvoke(memberExpr);
|
|
}
|
|
object reval = null;
|
|
var pro = (PropertyInfo)memberExpr.Member;
|
|
reval = pro.GetValue(memberExpr.Member, null);
|
|
if (reval != null && reval.GetType().IsClass() && reval.GetType() != UtilConstants.StringType)
|
|
{
|
|
var fieldName = memberExpr.Member.Name;
|
|
var proInfo = reval.GetType().GetProperty(fieldName);
|
|
if (proInfo != null)
|
|
{
|
|
reval = proInfo.GetValue(reval, null);
|
|
}
|
|
var fieInfo = reval.GetType().GetField(fieldName);
|
|
if (fieInfo != null)
|
|
{
|
|
reval = fieInfo.GetValue(reval);
|
|
}
|
|
if (fieInfo == null && proInfo == null)
|
|
{
|
|
Check.Exception(true, $" Property \"{pro.Name}\" can't be private ");
|
|
}
|
|
}
|
|
return reval;
|
|
}
|
|
|
|
public static object DynamicInvoke(Expression expression, MemberExpression memberExpression = null)
|
|
{
|
|
var value = Expression.Lambda(expression).Compile().DynamicInvoke();
|
|
if (value != null && value.GetType().IsClass() && value.GetType() != UtilConstants.StringType && memberExpression != null)
|
|
{
|
|
value = Expression.Lambda(memberExpression).Compile().DynamicInvoke();
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
public static Type GetPropertyOrFieldType(MemberInfo propertyOrField)
|
|
{
|
|
if (propertyOrField.MemberType == MemberTypes.Property)
|
|
return ((PropertyInfo)propertyOrField).PropertyType;
|
|
if (propertyOrField.MemberType == MemberTypes.Field)
|
|
return ((FieldInfo)propertyOrField).FieldType;
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
public static bool IsEntity(Type type)
|
|
{
|
|
return type.IsClass() && type != UtilConstants.StringType;
|
|
}
|
|
|
|
public static bool IsValueType(Type type)
|
|
{
|
|
return !IsEntity(type);
|
|
}
|
|
}
|
|
}
|