OneToOneNavgateExpression.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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 OneToOneNavgateExpression
  11. {
  12. public ExpressionContext ExpContext;
  13. private SqlSugarProvider context;
  14. internal EntityInfo EntityInfo;
  15. internal EntityInfo ProPertyEntity;
  16. private Navigate Navigat;
  17. public string ShorName;
  18. internal string MemberName;
  19. private MemberExpressionResolve _memberExpressionResolve;
  20. public OneToOneNavgateExpression(SqlSugarProvider context, MemberExpressionResolve memberExpressionResolve)
  21. {
  22. this.context = context;
  23. _memberExpressionResolve= memberExpressionResolve;
  24. }
  25. internal bool IsNavgate(Expression expression)
  26. {
  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 = ValidateNav(result, memberExp, childExpression);
  38. }
  39. return result;
  40. }
  41. private bool ValidateNav(bool result, MemberExpression memberExp, Expression childExpression)
  42. {
  43. if (childExpression != null && childExpression is MemberExpression)
  44. {
  45. var child2Expression = (childExpression as MemberExpression).Expression;
  46. if (child2Expression == null)
  47. {
  48. return false;
  49. }
  50. if (child2Expression.Type.IsClass() && child2Expression is ParameterExpression)
  51. {
  52. var entity = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type);
  53. if (entity.Columns.Any(x => x.PropertyName == (childExpression as MemberExpression).Member.Name && x.Navigat != null))
  54. {
  55. EntityInfo = entity;
  56. ShorName = child2Expression.ToString();
  57. MemberName = memberExp.Member.Name;
  58. ProPertyEntity = this.context.EntityMaintenance.GetEntityInfo(childExpression.Type);
  59. Navigat = entity.Columns.FirstOrDefault(x => x.PropertyName == (childExpression as MemberExpression).Member.Name).Navigat;
  60. result = true;
  61. }
  62. }
  63. }
  64. return result;
  65. }
  66. internal MapperSql GetSql()
  67. {
  68. if (this.ProPertyEntity.Type.Name.StartsWith("List`"))
  69. {
  70. Check.ExceptionEasy(true, " expression error ", "导航查询出错,比如.Count要改成 .Count()");
  71. }
  72. else if (Navigat.NavigatType == NavigateType.Dynamic)
  73. {
  74. Check.ExceptionEasy(
  75. true,
  76. " NavigateType.Dynamic no support expression . "+ this.ProPertyEntity.Type.Name,
  77. " NavigateType.Dynamic 自定义导航对象不支持在Where(x=>x.自定义.Id==1)等方法中使用"+ this.ProPertyEntity.Type.Name);
  78. }
  79. var pk = this.ProPertyEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true)?.DbColumnName;
  80. if (Navigat.Name2.HasValue())
  81. {
  82. pk = this.ProPertyEntity.Columns.FirstOrDefault(it => it.PropertyName == Navigat.Name2)?.DbColumnName;
  83. }
  84. if(pk==null)
  85. {
  86. Check.ExceptionEasy(
  87. true,
  88. $"{this.ProPertyEntity.EntityName} naviate config error",
  89. $"{this.ProPertyEntity.EntityName} 导航配置错误");
  90. }
  91. var name = this.EntityInfo.Columns.First(it => it.PropertyName == Navigat.Name).DbColumnName;
  92. var selectName = this.ProPertyEntity.Columns.First(it => it.PropertyName ==MemberName).DbColumnName;
  93. MapperSql mapper = new MapperSql();
  94. var queryable = this.context.Queryable<object>();
  95. pk = queryable.QueryBuilder.Builder.GetTranslationColumnName(pk);
  96. name = queryable.QueryBuilder.Builder.GetTranslationColumnName(name);
  97. selectName = queryable.QueryBuilder.Builder.GetTranslationColumnName(selectName);
  98. var tableName = this.ProPertyEntity.DbTableName;
  99. if (ExpContext?.SugarContext?.QueryBuilder?.IsCrossQueryWithAttr==true)
  100. {
  101. var attr= this.ProPertyEntity.Type.GetCustomAttribute<TenantAttribute>();
  102. var configId = ((object)this.context.CurrentConnectionConfig.ConfigId).ObjToString();
  103. if (attr != null&& configId != attr.configId.ObjToString())
  104. {
  105. var dbName = this.context.Root.GetConnection(attr.configId).Ado.Connection.Database;
  106. tableName = queryable.QueryBuilder.LambdaExpressions.DbMehtods.GetTableWithDataBase
  107. (queryable.QueryBuilder.Builder.GetTranslationColumnName(dbName), queryable.QueryBuilder.Builder.GetTranslationColumnName(tableName));
  108. }
  109. }
  110. Type[] clearTypes = null;
  111. var isClearFilter = false;
  112. if (this._memberExpressionResolve?.Context?.SugarContext?.QueryBuilder != null)
  113. {
  114. queryable.QueryBuilder.LambdaExpressions.ParameterIndex = 500 + this._memberExpressionResolve.Context.SugarContext.QueryBuilder.LambdaExpressions.ParameterIndex;
  115. this._memberExpressionResolve.Context.SugarContext.QueryBuilder.LambdaExpressions.ParameterIndex++;
  116. isClearFilter = this._memberExpressionResolve.Context.SugarContext.QueryBuilder.IsDisabledGobalFilter;
  117. clearTypes = this._memberExpressionResolve.Context.SugarContext.QueryBuilder.RemoveFilters;
  118. }
  119. var type = this.ProPertyEntity.Columns.Count(it => it.IsPrimarykey) > 1 ? this.ProPertyEntity.Type : null;
  120. if (isClearFilter)
  121. {
  122. type = null;
  123. }
  124. var sqlObj = queryable
  125. .AS(tableName)
  126. .ClearFilter(clearTypes)
  127. .Filter(type)
  128. .WhereIF(Navigat.WhereSql.HasValue(), Navigat.WhereSql)
  129. .Where($" {queryable.SqlBuilder.GetTranslationColumnName(ShorName)}.{name}={pk} ").Select(selectName).ToSql();
  130. mapper.Sql = sqlObj.Key;
  131. mapper.Sql = $" ({mapper.Sql}) ";
  132. if (type!=null&sqlObj.Value?.Any() == true)
  133. {
  134. foreach (var item in sqlObj.Value)
  135. {
  136. if (!this._memberExpressionResolve.Context.Parameters.Any(it => it.ParameterName == item.ParameterName))
  137. {
  138. this._memberExpressionResolve.Context.Parameters.Add(item);
  139. }
  140. }
  141. }
  142. return mapper;
  143. }
  144. }
  145. }