OneToOneNavgateExpressionN.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Reflection;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace SqlSugar
  9. {
  10. internal class OneToOneNavgateExpressionN
  11. {
  12. #region Constructor
  13. public string shorName { get; set; }
  14. public EntityInfo entityInfo;
  15. public List<ExpressionItems> items;
  16. public SqlSugarProvider context;
  17. public ISqlBuilder builder;
  18. public OneToOneNavgateExpressionN(SqlSugarProvider context)
  19. {
  20. this.context = context;
  21. }
  22. #endregion
  23. #region Api&Core
  24. public bool IsNavgate(Expression expression)
  25. {
  26. if (this.context == null) return false;
  27. var result = false;
  28. var exp = expression;
  29. if (exp is UnaryExpression)
  30. {
  31. exp = (exp as UnaryExpression).Operand;
  32. }
  33. if (exp is MemberExpression)
  34. {
  35. var memberExp = exp as MemberExpression;
  36. var childExpression = memberExp.Expression;
  37. result = ValidateIsJoinMember(result, memberExp, childExpression);
  38. }
  39. return result;
  40. }
  41. public MapperSql GetMemberSql()
  42. {
  43. MapperSql MapperSql = new MapperSql();
  44. var memberInfo = this.items.Where(it => it.Type == 1).First();
  45. var subInfos = this.items.Where(it => it.Type == 2).Reverse().ToList();
  46. var formInfo = subInfos.First();
  47. var joinInfos = subInfos.Skip(1).ToList();
  48. var i = 0;
  49. var masterShortName = formInfo.ThisEntityInfo.DbTableName + i;
  50. var queryable = this.context.Queryable<object>(ToShortName(masterShortName)).AS(formInfo.ThisEntityInfo.DbTableName).Filter(null,true);
  51. builder = queryable.SqlBuilder;
  52. i++;
  53. var lastShortName = "";
  54. foreach (var item in joinInfos)
  55. {
  56. var shortName = item.ThisEntityInfo.DbTableName + i;
  57. var pkColumn = item.ThisEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey);
  58. if (item.Nav.Name2.HasValue())
  59. {
  60. var nav2NameColumn = item.ThisEntityInfo.Columns.FirstOrDefault(it => it.PropertyName==item.Nav.Name2);
  61. if (nav2NameColumn != null)
  62. {
  63. pkColumn = nav2NameColumn;
  64. }
  65. }
  66. var navColum = item.ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.Nav.Name);
  67. Check.ExceptionEasy(pkColumn == null, $"{item.ThisEntityInfo.EntityName} need PrimayKey", $"使用导航属性{item.ThisEntityInfo.EntityName} 缺少主键");
  68. var on = $" {ToShortName(shortName)}.{queryable.SqlBuilder.GetTranslationColumnName(pkColumn.DbColumnName)}={ToShortName(formInfo.ThisEntityInfo.DbTableName + (i - 1))}.{queryable.SqlBuilder.GetTranslationColumnName(navColum.DbColumnName)}";
  69. if (item.Nav.WhereSql.HasValue())
  70. {
  71. on = (on + " AND " + item.Nav.WhereSql);
  72. }
  73. queryable.AddJoinInfo(item.ThisEntityInfo.DbTableName,ToShortName(shortName), on, JoinType.Inner);
  74. ++i;
  75. lastShortName = shortName;
  76. formInfo = item;
  77. }
  78. var selectProperyInfo = ExpressionTool.GetMemberName(memberInfo.Expression);
  79. var selectColumnInfo = memberInfo.ParentEntityInfo.Columns.First(it => it.PropertyName == selectProperyInfo);
  80. queryable.Select($" {ToShortName(lastShortName)}.{queryable.SqlBuilder.GetTranslationColumnName(selectColumnInfo.DbColumnName)}");
  81. var last = subInfos.First();
  82. var FirstPkColumn = last.ThisEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey);
  83. if (last.Nav.Name2.HasValue())
  84. {
  85. var nav2 = last.ThisEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == last.Nav.Name2);
  86. if (nav2 != null)
  87. {
  88. FirstPkColumn = nav2;
  89. }
  90. }
  91. Check.ExceptionEasy(FirstPkColumn == null, $"{ last.ThisEntityInfo.EntityName} need PrimayKey", $"使用导航属性{ last.ThisEntityInfo.EntityName} 缺少主键");
  92. var PkColumn = last.ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == last.Nav.Name);
  93. Check.ExceptionEasy(PkColumn == null, $"{ last.ParentEntityInfo.EntityName} no found {last.Nav.Name}", $"{ last.ParentEntityInfo.EntityName} 不存在 {last.Nav.Name}");
  94. queryable.Where($" {ToShortName(this.shorName)}.{queryable.SqlBuilder.GetTranslationColumnName(PkColumn.DbColumnName)} = {ToShortName(masterShortName)}.{queryable.SqlBuilder.GetTranslationColumnName(FirstPkColumn.DbColumnName)} ");
  95. MapperSql.Sql = "( " + queryable.ToSql().Key + " ) ";
  96. return MapperSql;
  97. }
  98. private bool ValidateIsJoinMember(bool result, MemberExpression memberExp, Expression childExpression)
  99. {
  100. if (childExpression != null && childExpression is MemberExpression)
  101. {
  102. var oldChildExpression = childExpression;
  103. var child2Expression = (childExpression as MemberExpression).Expression;
  104. if (child2Expression == null||(child2Expression is ConstantExpression))
  105. {
  106. return false;
  107. }
  108. items = new List<ExpressionItems>();
  109. items.Add(new ExpressionItems() { Type=1 , Expression= memberExp, ParentEntityInfo= this.context.EntityMaintenance.GetEntityInfo(oldChildExpression.Type )});
  110. items.Add(new ExpressionItems() { Type = 2, Expression = oldChildExpression, ThisEntityInfo=this.context.EntityMaintenance.GetEntityInfo(oldChildExpression.Type), ParentEntityInfo = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type) });
  111. if (items.Any(it => it.Type == 2 && it.Nav == null))
  112. {
  113. return false;
  114. }
  115. while (child2Expression != null)
  116. {
  117. if (IsClass(child2Expression))
  118. {
  119. items.Add(new ExpressionItems() { Type = 2, Expression = child2Expression, ThisEntityInfo=this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type), ParentEntityInfo = this.context.EntityMaintenance.GetEntityInfo(GetMemberExpression(child2Expression).Type) });
  120. child2Expression = GetMemberExpression(child2Expression);
  121. }
  122. else if (IsParameter(child2Expression))
  123. {
  124. shorName = child2Expression.ToString();
  125. entityInfo = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type);
  126. break;
  127. }
  128. else
  129. {
  130. break;
  131. }
  132. }
  133. if (!items.Any(it => it.Type == 2 && it.Nav == null))
  134. {
  135. return true;
  136. }
  137. }
  138. return result;
  139. }
  140. #endregion
  141. #region Helper
  142. private string ToShortName(string name)
  143. {
  144. var result = "";
  145. if (name.ObjToString().Contains("."))
  146. {
  147. if (this.context!= null)
  148. {
  149. var sqlBuilder = this.context.Queryable<object>().SqlBuilder;
  150. result = sqlBuilder.SqlTranslationLeft + name.Replace(".", "_") + sqlBuilder.SqlTranslationRight;
  151. return result;
  152. }
  153. else
  154. {
  155. result = name.Replace(".", "_");
  156. }
  157. }
  158. else
  159. {
  160. result= name;
  161. }
  162. if (builder == null) return name;
  163. return builder.GetTranslationColumnName(name);
  164. }
  165. private static bool IsParameter(Expression child2Expression)
  166. {
  167. return child2Expression.Type.IsClass() && child2Expression is ParameterExpression;
  168. }
  169. private static Expression GetMemberExpression(Expression child2Expression)
  170. {
  171. return (child2Expression as MemberExpression).Expression;
  172. }
  173. private static bool IsClass(Expression child2Expression)
  174. {
  175. return child2Expression.Type.IsClass() && child2Expression is MemberExpression;
  176. }
  177. #endregion
  178. }
  179. }