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.

369 lines
18 KiB

2 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq.Expressions;
  4. namespace SqlSugar
  5. {
  6. public class MemberExpressionResolve : BaseResolve
  7. {
  8. public ExpressionParameter Parameter { get; set; }
  9. public MemberExpressionResolve(ExpressionParameter parameter) : base(parameter)
  10. {
  11. ExpressionParameter baseParameter;
  12. MemberExpression expression;
  13. bool? isLeft;
  14. bool isSetTempData, isValue, isValueBool, isLength, isDateValue, isHasValue, isDateDate, isMemberValue, isSingle, fieldIsBool, isSelectField, isField;
  15. SettingParameters(parameter, out baseParameter, out expression, out isLeft, out isSetTempData, out isValue, out isValueBool, out isLength, out isDateValue, out isHasValue, out isDateDate, out isMemberValue, out isSingle, out fieldIsBool, out isSelectField, out isField);
  16. baseParameter.ChildExpression = expression;
  17. if (isLength)
  18. {
  19. ResolveLength(parameter, isLeft, expression);
  20. }
  21. else if (isHasValue)
  22. {
  23. ResolveHasValue(parameter, expression);
  24. }
  25. else if (isDateValue)
  26. {
  27. ResolveDateValue(parameter, isLeft, expression);
  28. }
  29. else if (isValueBool)
  30. {
  31. ResolveValueBool(parameter, baseParameter, expression, isLeft, isSingle);
  32. }
  33. else if (isValue)
  34. {
  35. ResolveValue(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle);
  36. }
  37. else if (isDateDate)
  38. {
  39. ResolveDateDate(parameter, isLeft, expression);
  40. }
  41. else if (isMemberValue)
  42. {
  43. ResolveMemberValue(parameter, baseParameter, isLeft, isSetTempData, expression);
  44. }
  45. else if (fieldIsBool && !isField && !isSelectField)
  46. {
  47. ResolvefieldIsBool(parameter, baseParameter, isLeft, isSetTempData, expression, isSingle);
  48. }
  49. else
  50. {
  51. ResolveDefault(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle);
  52. }
  53. }
  54. #region Resolve default
  55. private void ResolveDefault(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSetTempData, bool isSingle)
  56. {
  57. var fieldName = string.Empty;
  58. switch (parameter.Context.ResolveType)
  59. {
  60. case ResolveExpressType.SelectSingle:
  61. fieldName = GetSingleName(parameter, expression, isLeft);
  62. if (isSetTempData)
  63. baseParameter.CommonTempData = fieldName;
  64. else
  65. base.Context.Result.Append(fieldName);
  66. break;
  67. case ResolveExpressType.SelectMultiple:
  68. fieldName = GetMultipleName(parameter, expression, isLeft);
  69. if (isSetTempData)
  70. baseParameter.CommonTempData = fieldName;
  71. else
  72. base.Context.Result.Append(fieldName);
  73. break;
  74. case ResolveExpressType.WhereSingle:
  75. case ResolveExpressType.WhereMultiple:
  76. ResolveWhereLogic(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle);
  77. break;
  78. case ResolveExpressType.FieldSingle:
  79. fieldName = GetSingleName(parameter, expression, isLeft);
  80. base.Context.Result.Append(fieldName);
  81. break;
  82. case ResolveExpressType.FieldMultiple:
  83. fieldName = GetMultipleName(parameter, expression, isLeft);
  84. base.Context.Result.Append(fieldName);
  85. break;
  86. case ResolveExpressType.ArrayMultiple:
  87. case ResolveExpressType.ArraySingle:
  88. fieldName = GetName(parameter, expression, isLeft, parameter.Context.ResolveType == ResolveExpressType.ArraySingle);
  89. base.Context.Result.Append(fieldName);
  90. break;
  91. default:
  92. break;
  93. }
  94. }
  95. #endregion
  96. #region Resolve Where
  97. private void ResolveWhereLogic(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSetTempData, bool isSingle)
  98. {
  99. var fieldName = string.Empty;
  100. if (isSetTempData)
  101. {
  102. if (ExpressionTool.IsConstExpression(expression))
  103. {
  104. var value = ExpressionTool.GetMemberValue(expression.Member, expression);
  105. baseParameter.CommonTempData = value;
  106. }
  107. else
  108. {
  109. fieldName = GetName(parameter, expression, null, isSingle);
  110. baseParameter.CommonTempData = fieldName;
  111. }
  112. }
  113. else
  114. {
  115. if (ExpressionTool.IsConstExpression(expression))
  116. {
  117. var value = ExpressionTool.GetMemberValue(expression.Member, expression);
  118. base.AppendValue(parameter, isLeft, value);
  119. }
  120. else
  121. {
  122. fieldName = GetName(parameter, expression, isLeft, isSingle);
  123. AppendMember(parameter, isLeft, fieldName);
  124. }
  125. }
  126. }
  127. #endregion
  128. #region Resolve special member
  129. private MemberExpression ResolveValue(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSetTempData, bool isSingle)
  130. {
  131. expression = expression.Expression as MemberExpression;
  132. baseParameter.ChildExpression = expression;
  133. ResolveWhereLogic(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle);
  134. return expression;
  135. }
  136. private void ResolveValueBool(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSingle)
  137. {
  138. var fieldName = GetName(parameter, expression.Expression as MemberExpression, isLeft, isSingle);
  139. if (expression.Type == UtilConstants.BoolType && baseParameter.OperatorValue.IsNullOrEmpty())
  140. {
  141. fieldName = this.Context.DbMehtods.EqualTrue(fieldName);
  142. }
  143. AppendMember(parameter, isLeft, fieldName);
  144. }
  145. private void ResolveMemberValue(ExpressionParameter parameter, ExpressionParameter baseParameter, bool? isLeft, bool isSetTempData, MemberExpression expression)
  146. {
  147. var value = ExpressionTool.GetMemberValue(expression.Member, expression);
  148. if (isSetTempData)
  149. {
  150. baseParameter.CommonTempData = value;
  151. }
  152. else
  153. {
  154. AppendValue(parameter, isLeft, value);
  155. }
  156. }
  157. private void ResolvefieldIsBool(ExpressionParameter parameter, ExpressionParameter baseParameter, bool? isLeft, bool isSetTempData, MemberExpression expression, bool isSingle)
  158. {
  159. var fieldName = GetName(parameter, expression, isLeft, isSingle);
  160. if (isSetTempData)
  161. {
  162. baseParameter.CommonTempData = fieldName;
  163. }
  164. else
  165. {
  166. fieldName = this.Context.DbMehtods.EqualTrue(fieldName.ObjToString());
  167. AppendMember(parameter, isLeft, fieldName);
  168. }
  169. }
  170. private void ResolveDateDate(ExpressionParameter parameter, bool? isLeft, MemberExpression expression)
  171. {
  172. var name = expression.Member.Name;
  173. var oldCommonTempDate = parameter.CommonTempData;
  174. parameter.CommonTempData = CommonTempDataType.Result;
  175. this.Expression = expression.Expression;
  176. this.Start();
  177. var isConst = parameter.CommonTempData.GetType() == UtilConstants.DateType;
  178. if (isConst)
  179. {
  180. AppendValue(parameter, isLeft, parameter.CommonTempData.ObjToDate().Date);
  181. }
  182. else
  183. {
  184. var GetYear = new MethodCallExpressionModel
  185. {
  186. Args = new List<MethodCallExpressionArgs> {
  187. new MethodCallExpressionArgs { IsMember=true, MemberName=parameter.CommonTempData, MemberValue=parameter.CommonTempData },
  188. new MethodCallExpressionArgs { MemberName=DateType.Year, MemberValue=DateType.Year}
  189. }
  190. };
  191. AppendMember(parameter, isLeft, GetToDate(this.Context.DbMehtods.MergeString(
  192. this.GetDateValue(parameter.CommonTempData, DateType.Year),
  193. "'-'",
  194. this.GetDateValue(parameter.CommonTempData, DateType.Month),
  195. "'-'",
  196. this.GetDateValue(parameter.CommonTempData, DateType.Day))));
  197. }
  198. parameter.CommonTempData = oldCommonTempDate;
  199. }
  200. private void ResolveDateValue(ExpressionParameter parameter, bool? isLeft, MemberExpression expression)
  201. {
  202. var name = expression.Member.Name;
  203. var oldCommonTempDate = parameter.CommonTempData;
  204. parameter.CommonTempData = CommonTempDataType.Result;
  205. this.Expression = expression.Expression;
  206. var isConst = this.Expression is ConstantExpression;
  207. this.Start();
  208. var result = this.Context.DbMehtods.DateValue(new MethodCallExpressionModel
  209. {
  210. Args = new List<MethodCallExpressionArgs> {
  211. new MethodCallExpressionArgs { IsMember = !isConst, MemberName = parameter.CommonTempData, MemberValue = null },
  212. new MethodCallExpressionArgs { IsMember = true, MemberName = name, MemberValue = name }
  213. }
  214. });
  215. base.AppendMember(parameter, isLeft, result);
  216. parameter.CommonTempData = oldCommonTempDate;
  217. }
  218. private void ResolveHasValue(ExpressionParameter parameter, MemberExpression expression)
  219. {
  220. parameter.CommonTempData = CommonTempDataType.Result;
  221. this.Expression = expression.Expression;
  222. this.Start();
  223. var methodParamter = new MethodCallExpressionArgs { IsMember = true, MemberName = parameter.CommonTempData, MemberValue = null };
  224. var result = this.Context.DbMehtods.HasValue(new MethodCallExpressionModel
  225. {
  226. Args = new List<MethodCallExpressionArgs> {
  227. methodParamter
  228. }
  229. });
  230. this.Context.Result.Append(result);
  231. parameter.CommonTempData = null;
  232. }
  233. private void ResolveLength(ExpressionParameter parameter, bool? isLeft, MemberExpression expression)
  234. {
  235. var oldCommonTempDate = parameter.CommonTempData;
  236. parameter.CommonTempData = CommonTempDataType.Result;
  237. this.Expression = expression.Expression;
  238. var isConst = this.Expression is ConstantExpression;
  239. this.Start();
  240. var methodParamter = new MethodCallExpressionArgs { IsMember = !isConst, MemberName = parameter.CommonTempData, MemberValue = null };
  241. var result = this.Context.DbMehtods.Length(new MethodCallExpressionModel
  242. {
  243. Args = new List<MethodCallExpressionArgs> {
  244. methodParamter
  245. }
  246. });
  247. base.AppendMember(parameter, isLeft, result);
  248. parameter.CommonTempData = oldCommonTempDate;
  249. }
  250. #endregion
  251. #region Helper
  252. private string AppendMember(ExpressionParameter parameter, bool? isLeft, string fieldName)
  253. {
  254. if (parameter.BaseExpression is BinaryExpression || (parameter.BaseParameter.CommonTempData != null && parameter.BaseParameter.CommonTempData.Equals(CommonTempDataType.Append)))
  255. {
  256. fieldName = string.Format(" {0} ", fieldName);
  257. if (isLeft == true)
  258. {
  259. fieldName += ExpressionConst.ExpressionReplace + parameter.BaseParameter.Index;
  260. }
  261. if (base.Context.Result.Contains(ExpressionConst.FormatSymbol))
  262. {
  263. base.Context.Result.Replace(ExpressionConst.FormatSymbol, fieldName);
  264. }
  265. else
  266. {
  267. base.Context.Result.Append(fieldName);
  268. }
  269. }
  270. else
  271. {
  272. base.Context.Result.Append(fieldName);
  273. }
  274. return fieldName;
  275. }
  276. private string GetName(ExpressionParameter parameter, MemberExpression expression, bool? isLeft, bool isSingle)
  277. {
  278. if (isSingle)
  279. {
  280. return GetSingleName(parameter, expression, IsLeft);
  281. }
  282. else
  283. {
  284. return GetMultipleName(parameter, expression, IsLeft);
  285. }
  286. }
  287. private string GetMultipleName(ExpressionParameter parameter, MemberExpression expression, bool? isLeft)
  288. {
  289. var shortName = expression.Expression.ToString();
  290. var fieldName = expression.Member.Name;
  291. fieldName = this.Context.GetDbColumnName(expression.Expression.Type.Name, fieldName);
  292. fieldName = Context.GetTranslationColumnName(shortName + UtilConstants.Dot + fieldName);
  293. return fieldName;
  294. }
  295. private string GetSingleName(ExpressionParameter parameter, MemberExpression expression, bool? isLeft)
  296. {
  297. var fieldName = expression.Member.Name;
  298. fieldName = this.Context.GetDbColumnName(expression.Expression.Type.Name, fieldName);
  299. fieldName = Context.GetTranslationColumnName(fieldName);
  300. return fieldName;
  301. }
  302. private string GetDateValue(object value, DateType type)
  303. {
  304. var pars = new MethodCallExpressionModel
  305. {
  306. Args = new List<MethodCallExpressionArgs> {
  307. new MethodCallExpressionArgs { IsMember=true, MemberName=value, MemberValue=value },
  308. new MethodCallExpressionArgs { MemberName=type, MemberValue=type}
  309. }
  310. };
  311. return this.Context.DbMehtods.DateValue(pars);
  312. }
  313. private string GetToDate(string value)
  314. {
  315. var pars = new MethodCallExpressionModel
  316. {
  317. Args = new List<MethodCallExpressionArgs> {
  318. new MethodCallExpressionArgs { MemberName=value, MemberValue=value },
  319. }
  320. };
  321. return this.Context.DbMehtods.ToDate(pars);
  322. }
  323. private void SettingParameters(ExpressionParameter parameter, out ExpressionParameter baseParameter, out MemberExpression expression, out bool? isLeft, out bool isSetTempData, out bool isValue, out bool isValueBool, out bool isLength, out bool isDateValue, out bool isHasValue, out bool isDateDate, out bool isMemberValue, out bool isSingle, out bool fieldIsBool, out bool isSelectField, out bool isField)
  324. {
  325. baseParameter = parameter.BaseParameter;
  326. expression = base.Expression as MemberExpression;
  327. var childExpression = expression.Expression as MemberExpression;
  328. var memberName = expression.Member.Name;
  329. var childIsMember = childExpression != null;
  330. var isRoot = parameter.BaseExpression == null;
  331. isLeft = parameter.IsLeft;
  332. isSetTempData = parameter.IsSetTempData;
  333. isValue = memberName == "Value" && expression.Member.DeclaringType.Name == "Nullable`1";
  334. var isBool = expression.Type == UtilConstants.BoolType;
  335. isValueBool = isValue && isBool && isRoot;
  336. isLength = memberName == "Length" && childIsMember && childExpression.Type == UtilConstants.StringType;
  337. isDateValue = memberName.IsIn(Enum.GetNames(typeof(DateType))) && (childIsMember && childExpression.Type == UtilConstants.DateType);
  338. var isLogicOperator = ExpressionTool.IsLogicOperator(baseParameter.OperatorValue) || baseParameter.OperatorValue.IsNullOrEmpty();
  339. isHasValue = isLogicOperator && memberName == "HasValue" && expression.Expression != null && expression.NodeType == ExpressionType.MemberAccess;
  340. isDateDate = memberName == "Date" && expression.Expression.Type == UtilConstants.DateType;
  341. isMemberValue = expression.Expression != null && expression.Expression.NodeType != ExpressionType.Parameter && !isValueBool;
  342. isSingle = parameter.Context.ResolveType.IsIn(ResolveExpressType.WhereSingle, ResolveExpressType.SelectSingle, ResolveExpressType.FieldSingle, ResolveExpressType.ArraySingle);
  343. fieldIsBool = isBool && isLogicOperator && (parameter.BaseParameter == null || !(parameter.BaseParameter.CurrentExpression is MemberInitExpression || parameter.BaseParameter.CurrentExpression is NewExpression));
  344. var isSelect = this.Context.ResolveType.IsIn(ResolveExpressType.SelectSingle, ResolveExpressType.SelectMultiple);
  345. isSelectField = isSelect && isRoot;
  346. isField = this.Context.ResolveType.IsIn(ResolveExpressType.FieldSingle, ResolveExpressType.FieldMultiple);
  347. }
  348. #endregion
  349. }
  350. }