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.

254 lines
9.6 KiB

2 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq.Expressions;
  4. using System.Reflection;
  5. namespace SqlSugar
  6. {
  7. public class ExpressionTool
  8. {
  9. public static string GetOperator(ExpressionType expressiontype)
  10. {
  11. switch (expressiontype)
  12. {
  13. case ExpressionType.And:
  14. case ExpressionType.AndAlso:
  15. return "AND";
  16. case ExpressionType.Equal:
  17. return "=";
  18. case ExpressionType.GreaterThan:
  19. return ">";
  20. case ExpressionType.GreaterThanOrEqual:
  21. return ">=";
  22. case ExpressionType.LessThan:
  23. return "<";
  24. case ExpressionType.LessThanOrEqual:
  25. return "<=";
  26. case ExpressionType.NotEqual:
  27. return "<>";
  28. case ExpressionType.Or:
  29. case ExpressionType.OrElse:
  30. return "OR";
  31. case ExpressionType.Add:
  32. case ExpressionType.AddChecked:
  33. return "+";
  34. case ExpressionType.Subtract:
  35. case ExpressionType.SubtractChecked:
  36. return "-";
  37. case ExpressionType.Divide:
  38. return "/";
  39. case ExpressionType.Multiply:
  40. case ExpressionType.MultiplyChecked:
  41. return "*";
  42. case ExpressionType.Coalesce:
  43. throw new Exception("Expression no support ?? ,Use SqlFunc.IsNull");
  44. default:
  45. Check.ThrowNotSupportedException(string.Format(ErrorMessage.OperatorError, expressiontype.ToString()));
  46. return null;
  47. }
  48. }
  49. public static object GetValue(object value)
  50. {
  51. if (value == null) return value;
  52. var type = value.GetType();
  53. if (type.IsEnum() && type != typeof(DateType) && type != typeof(JoinType) && type != typeof(OrderByType)) return Convert.ToInt64(value);
  54. else
  55. return value;
  56. }
  57. public static bool IsLogicOperator(string operatorValue)
  58. {
  59. return operatorValue == "&&" || operatorValue == "||" || operatorValue == "AND" || operatorValue == "OR";
  60. }
  61. public static bool IsLogicOperator(Expression expression)
  62. {
  63. return expression.NodeType == ExpressionType.And ||
  64. expression.NodeType == ExpressionType.AndAlso ||
  65. expression.NodeType == ExpressionType.Or ||
  66. expression.NodeType == ExpressionType.OrElse;
  67. }
  68. public static bool IsComparisonOperator(Expression expression)
  69. {
  70. return expression.NodeType != ExpressionType.And &&
  71. expression.NodeType != ExpressionType.AndAlso &&
  72. expression.NodeType != ExpressionType.Or &&
  73. expression.NodeType != ExpressionType.OrElse;
  74. }
  75. public static object GetMemberValue(MemberInfo member, Expression expression)
  76. {
  77. var rootExpression = expression as MemberExpression;
  78. var memberInfos = new Stack<MemberInfo>();
  79. var fieldInfo = member as System.Reflection.FieldInfo;
  80. object reval = null;
  81. MemberExpression memberExpr = null;
  82. while (expression is MemberExpression)
  83. {
  84. memberExpr = expression as MemberExpression;
  85. memberInfos.Push(memberExpr.Member);
  86. if (memberExpr.Expression == null)
  87. {
  88. var isProperty = memberExpr.Member.MemberType == MemberTypes.Property;
  89. var isField = memberExpr.Member.MemberType == MemberTypes.Field;
  90. if (isProperty)
  91. {
  92. reval = GetPropertyValue(memberExpr);
  93. }
  94. else if (isField)
  95. {
  96. reval = GetFiledValue(memberExpr);
  97. }
  98. }
  99. if (memberExpr.Expression == null)
  100. {
  101. }
  102. expression = memberExpr.Expression;
  103. }
  104. // fetch the root object reference:
  105. var constExpr = expression as ConstantExpression;
  106. if (constExpr == null)
  107. {
  108. return DynamicInvoke(rootExpression);
  109. }
  110. var objReference = constExpr.Value;
  111. // "ascend" back whence we came from and resolve object references along the way:
  112. while (memberInfos.Count > 0) // or some other break condition
  113. {
  114. var mi = memberInfos.Pop();
  115. if (mi.MemberType == MemberTypes.Property)
  116. {
  117. var objProp = objReference.GetType().GetProperty(mi.Name);
  118. objReference = objProp == null ? DynamicInvoke(expression, rootExpression == null ? memberExpr : rootExpression) : objProp.GetValue(objReference, null);
  119. }
  120. else if (mi.MemberType == MemberTypes.Field)
  121. {
  122. var objField = objReference.GetType().GetField(mi.Name);
  123. objReference = objField == null ? DynamicInvoke(expression, rootExpression == null ? memberExpr : rootExpression) : objField.GetValue(objReference);
  124. }
  125. }
  126. reval = objReference;
  127. return reval;
  128. }
  129. public static object GetFiledValue(MemberExpression memberExpr)
  130. {
  131. if (!(memberExpr.Member is FieldInfo))
  132. {
  133. return DynamicInvoke(memberExpr);
  134. }
  135. object reval = null;
  136. var field = (FieldInfo)memberExpr.Member;
  137. Check.Exception(field.IsPrivate, $" Field \"{field.Name}\" can't be private ");
  138. reval = field.GetValue(memberExpr.Member);
  139. if (reval != null && reval.GetType().IsClass() && reval.GetType() != UtilConstants.StringType)
  140. {
  141. var fieldName = memberExpr.Member.Name;
  142. var proInfo = reval.GetType().GetProperty(fieldName);
  143. if (proInfo != null)
  144. {
  145. reval = proInfo.GetValue(reval, null);
  146. }
  147. var fieInfo = reval.GetType().GetField(fieldName);
  148. if (fieInfo != null)
  149. {
  150. reval = fieInfo.GetValue(reval);
  151. }
  152. if (fieInfo == null && proInfo == null)
  153. {
  154. Check.Exception(field.IsPrivate, $" Field \"{field.Name}\" can't be private ");
  155. }
  156. }
  157. return reval;
  158. }
  159. public static bool IsConstExpression(MemberExpression memberExpr)
  160. {
  161. var result = false;
  162. while (memberExpr != null && memberExpr.Expression != null)
  163. {
  164. var isConst = memberExpr.Expression is ConstantExpression;
  165. if (isConst)
  166. {
  167. result = true;
  168. break;
  169. }
  170. memberExpr = memberExpr.Expression as MemberExpression;
  171. }
  172. return result;
  173. }
  174. public static object GetPropertyValue(MemberExpression memberExpr)
  175. {
  176. if (!(memberExpr.Member is PropertyInfo))
  177. {
  178. return DynamicInvoke(memberExpr);
  179. }
  180. object reval = null;
  181. var pro = (PropertyInfo)memberExpr.Member;
  182. reval = pro.GetValue(memberExpr.Member, null);
  183. if (reval != null && reval.GetType().IsClass() && reval.GetType() != UtilConstants.StringType)
  184. {
  185. var fieldName = memberExpr.Member.Name;
  186. var proInfo = reval.GetType().GetProperty(fieldName);
  187. if (proInfo != null)
  188. {
  189. reval = proInfo.GetValue(reval, null);
  190. }
  191. var fieInfo = reval.GetType().GetField(fieldName);
  192. if (fieInfo != null)
  193. {
  194. reval = fieInfo.GetValue(reval);
  195. }
  196. if (fieInfo == null && proInfo == null)
  197. {
  198. Check.Exception(true, $" Property \"{pro.Name}\" can't be private ");
  199. }
  200. }
  201. return reval;
  202. }
  203. public static object DynamicInvoke(Expression expression, MemberExpression memberExpression = null)
  204. {
  205. var value = Expression.Lambda(expression).Compile().DynamicInvoke();
  206. if (value != null && value.GetType().IsClass() && value.GetType() != UtilConstants.StringType && memberExpression != null)
  207. {
  208. value = Expression.Lambda(memberExpression).Compile().DynamicInvoke();
  209. }
  210. return value;
  211. }
  212. public static Type GetPropertyOrFieldType(MemberInfo propertyOrField)
  213. {
  214. if (propertyOrField.MemberType == MemberTypes.Property)
  215. return ((PropertyInfo)propertyOrField).PropertyType;
  216. if (propertyOrField.MemberType == MemberTypes.Field)
  217. return ((FieldInfo)propertyOrField).FieldType;
  218. throw new NotSupportedException();
  219. }
  220. public static bool IsEntity(Type type)
  221. {
  222. return type.IsClass() && type != UtilConstants.StringType;
  223. }
  224. public static bool IsValueType(Type type)
  225. {
  226. return !IsEntity(type);
  227. }
  228. }
  229. }