DbExpressionExtensions.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. using Ant.DbExpressions;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Text;
  7. namespace Ant.Oracle
  8. {
  9. static class DbExpressionExtensions
  10. {
  11. /// <summary>
  12. /// 尝试将 exp 转换成 DbParameterExpression。
  13. /// </summary>
  14. /// <param name="exp"></param>
  15. /// <param name="val"></param>
  16. /// <returns></returns>
  17. public static bool TryParseToParameterExpression(this DbMemberExpression exp, out DbParameterExpression val)
  18. {
  19. val = null;
  20. if (!exp.CanEvaluate())
  21. return false;
  22. //求值
  23. val = exp.ParseToParameterExpression();
  24. return true;
  25. }
  26. /// <summary>
  27. /// 尝试将 exp 转换成 DbParameterExpression。
  28. /// </summary>
  29. /// <param name="exp"></param>
  30. /// <returns></returns>
  31. public static DbExpression ParseDbExpression(this DbExpression exp)
  32. {
  33. DbExpression stripedExp = DbExpressionHelper.StripInvalidConvert(exp);
  34. DbExpression tempExp = stripedExp;
  35. List<DbConvertExpression> cList = null;
  36. while (tempExp.NodeType == DbExpressionType.Convert)
  37. {
  38. if (cList == null)
  39. cList = new List<DbConvertExpression>();
  40. DbConvertExpression c = (DbConvertExpression)tempExp;
  41. cList.Add(c);
  42. tempExp = c.Operand;
  43. }
  44. if (tempExp.NodeType == DbExpressionType.Constant || tempExp.NodeType == DbExpressionType.Parameter)
  45. return stripedExp;
  46. if (tempExp.NodeType == DbExpressionType.MemberAccess)
  47. {
  48. DbMemberExpression dbMemberExp = (DbMemberExpression)tempExp;
  49. if (ExistDateTime_NowOrDateTime_UtcNow(dbMemberExp))
  50. return stripedExp;
  51. DbParameterExpression val;
  52. if (DbExpressionExtensions.TryParseToParameterExpression(dbMemberExp, out val))
  53. {
  54. if (cList != null)
  55. {
  56. if (val.Value == DBNull.Value)//如果是 null,则不需要 Convert 了,在数据库里没意义
  57. return val;
  58. DbConvertExpression c = null;
  59. for (int i = cList.Count - 1; i > -1; i--)
  60. {
  61. DbConvertExpression item = cList[i];
  62. c = new DbConvertExpression(item.Type, val);
  63. }
  64. return c;
  65. }
  66. return val;
  67. }
  68. }
  69. return stripedExp;
  70. }
  71. public static bool CanEvaluate(this DbMemberExpression memberExpression)
  72. {
  73. if (memberExpression == null)
  74. throw new ArgumentNullException("memberExpression");
  75. do
  76. {
  77. DbExpression prevExp = memberExpression.Expression;
  78. // prevExp == null 表示是静态成员
  79. if (prevExp == null || prevExp is DbConstantExpression)
  80. return true;
  81. DbMemberExpression memberExp = prevExp as DbMemberExpression;
  82. if (memberExp == null)
  83. return false;
  84. else
  85. memberExpression = memberExp;
  86. } while (true);
  87. }
  88. /// <summary>
  89. /// 对 memberExpression 进行求值
  90. /// </summary>
  91. /// <param name="exp"></param>
  92. /// <returns>返回 DbParameterExpression</returns>
  93. public static DbParameterExpression ParseToParameterExpression(this DbMemberExpression memberExpression)
  94. {
  95. DbParameterExpression ret = null;
  96. //求值
  97. object val = DbExpressionExtensions.GetExpressionValue(memberExpression);
  98. ret = DbExpression.Parameter(val, memberExpression.Type);
  99. return ret;
  100. }
  101. /// <summary>
  102. /// 判定 exp 返回值肯定是 null
  103. /// </summary>
  104. /// <param name="exp"></param>
  105. /// <returns></returns>
  106. public static bool AffirmExpressionRetValueIsNull(this DbExpression exp)
  107. {
  108. exp = DbExpressionHelper.StripConvert(exp);
  109. if (exp.NodeType == DbExpressionType.Constant)
  110. {
  111. var c = (DbConstantExpression)exp;
  112. return c.Value == null || c.Value == DBNull.Value;
  113. }
  114. if (exp.NodeType == DbExpressionType.Parameter)
  115. {
  116. var p = (DbParameterExpression)exp;
  117. return p.Value == null || p.Value == DBNull.Value;
  118. }
  119. return false;
  120. }
  121. /// <summary>
  122. /// 判定 exp 返回值肯定不是 null
  123. /// </summary>
  124. /// <param name="exp"></param>
  125. /// <returns></returns>
  126. public static bool AffirmExpressionRetValueIsNotNull(this DbExpression exp)
  127. {
  128. exp = DbExpressionHelper.StripConvert(exp);
  129. if (exp.NodeType == DbExpressionType.Constant)
  130. {
  131. var c = (DbConstantExpression)exp;
  132. return c.Value != null && c.Value != DBNull.Value;
  133. }
  134. if (exp.NodeType == DbExpressionType.Parameter)
  135. {
  136. var p = (DbParameterExpression)exp;
  137. return p.Value != null && p.Value != DBNull.Value;
  138. }
  139. return false;
  140. }
  141. public static object GetMemberAccessExpressionValue(this DbMemberExpression exp, object instance)
  142. {
  143. if (exp.Member.MemberType
  144. == MemberTypes.Field)
  145. {
  146. return ((FieldInfo)exp.Member).GetValue(instance);
  147. }
  148. else if (exp.Member.MemberType
  149. == MemberTypes.Property)
  150. {
  151. return ((PropertyInfo)exp.Member).GetValue(instance, null);
  152. }
  153. throw new NotSupportedException();
  154. }
  155. public static object GetExpressionValue(this DbExpression exp)
  156. {
  157. if (exp.NodeType == DbExpressionType.Constant)
  158. return ((DbConstantExpression)exp).Value;
  159. if (exp.NodeType == DbExpressionType.MemberAccess)
  160. {
  161. DbMemberExpression m = (DbMemberExpression)exp;
  162. object instance = null;
  163. if (m.Expression != null)
  164. instance = DbExpressionExtensions.GetExpressionValue(m.Expression);
  165. return GetMemberAccessExpressionValue(m, instance);
  166. }
  167. throw new NotSupportedException();
  168. }
  169. public static bool ExistDateTime_NowOrDateTime_UtcNow(this DbMemberExpression exp)
  170. {
  171. while (exp != null)
  172. {
  173. if (exp.Member == UtilConstants.PropertyInfo_DateTime_Now || exp.Member == UtilConstants.PropertyInfo_DateTime_UtcNow)
  174. {
  175. return true;
  176. }
  177. exp = exp.Expression as DbMemberExpression;
  178. }
  179. return false;
  180. }
  181. }
  182. }