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

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