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.

418 lines
19 KiB

2 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. namespace SqlSugar
  6. {
  7. public partial class SqlSugarClient
  8. {
  9. #region Properties
  10. public SqlSugarClient Context
  11. {
  12. get
  13. {
  14. var result = _Context; ;
  15. if (CurrentConnectionConfig.IsShardSameThread)
  16. {
  17. if (CallContext.ContextList.Value.IsNullOrEmpty())
  18. {
  19. CallContext.ContextList.Value = new List<SqlSugarClient>();
  20. CallContext.ContextList.Value.Add(_Context);
  21. }
  22. else
  23. {
  24. var cacheContext = CallContext.ContextList.Value.FirstOrDefault(it =>
  25. it.CurrentConnectionConfig.ConnectionString == _Context.CurrentConnectionConfig.ConnectionString &&
  26. it.CurrentConnectionConfig.DbType == _Context.CurrentConnectionConfig.DbType &&
  27. it.CurrentConnectionConfig.IsAutoCloseConnection == _Context.CurrentConnectionConfig.IsAutoCloseConnection &&
  28. it.CurrentConnectionConfig.IsShardSameThread == _Context.CurrentConnectionConfig.IsShardSameThread);
  29. if (cacheContext != null)
  30. {
  31. return cacheContext;
  32. }
  33. }
  34. }
  35. return result;
  36. }
  37. set
  38. {
  39. _Context = value;
  40. }
  41. }
  42. public ConnectionConfig CurrentConnectionConfig { get; set; }
  43. public Dictionary<string, object> TempItems { get; set; }
  44. public bool IsSystemTablesConfig { get { return this.CurrentConnectionConfig.InitKeyType == InitKeyType.SystemTable; } }
  45. public Guid ContextID { get; set; }
  46. public MappingTableList MappingTables = new MappingTableList();
  47. public MappingColumnList MappingColumns = new MappingColumnList();
  48. public IgnoreColumnList IgnoreColumns = new IgnoreColumnList();
  49. public IgnoreColumnList IgnoreInsertColumns = new IgnoreColumnList();
  50. #endregion
  51. #region Fields
  52. protected ISqlBuilder _SqlBuilder;
  53. protected SqlSugarClient _Context { get; set; }
  54. protected EntityMaintenance _EntityProvider;
  55. protected IAdo _Ado;
  56. protected ILambdaExpressions _LambdaExpressions;
  57. protected IContextMethods _RewritableMethods;
  58. protected IDbMaintenance _DbMaintenance;
  59. protected QueryFilterProvider _QueryFilterProvider;
  60. protected SimpleClient _SimpleClient;
  61. protected IAdo ContextAdo
  62. {
  63. get
  64. {
  65. return this.Context._Ado;
  66. }
  67. set
  68. {
  69. this.Context._Ado = value;
  70. }
  71. }
  72. protected IContextMethods ContextRewritableMethods
  73. {
  74. get
  75. {
  76. return this.Context._RewritableMethods;
  77. }
  78. set
  79. {
  80. this.Context._RewritableMethods = value;
  81. }
  82. }
  83. #endregion
  84. #region Init mppingInfo
  85. protected void InitMppingInfo<T, T2>()
  86. {
  87. InitMppingInfo<T>();
  88. InitMppingInfo<T2>();
  89. }
  90. protected void InitMppingInfo<T, T2, T3>()
  91. {
  92. InitMppingInfo<T, T2>();
  93. InitMppingInfo<T3>();
  94. }
  95. protected void InitMppingInfo<T, T2, T3, T4>()
  96. {
  97. InitMppingInfo<T, T2, T3>();
  98. InitMppingInfo<T4>();
  99. }
  100. protected void InitMppingInfo<T, T2, T3, T4, T5>()
  101. {
  102. InitMppingInfo<T, T2, T3, T4>();
  103. InitMppingInfo<T5>();
  104. }
  105. protected void InitMppingInfo<T, T2, T3, T4, T5, T6>()
  106. {
  107. InitMppingInfo<T, T2, T3, T4, T5>();
  108. InitMppingInfo<T6>();
  109. }
  110. protected void InitMppingInfo<T, T2, T3, T4, T5, T6, T7>()
  111. {
  112. InitMppingInfo<T, T2, T3, T4, T5, T6>();
  113. InitMppingInfo<T7>();
  114. }
  115. protected void InitMppingInfo<T, T2, T3, T4, T5, T6, T7, T8>()
  116. {
  117. InitMppingInfo<T, T2, T3, T4, T5, T6, T7>();
  118. InitMppingInfo<T8>();
  119. }
  120. #region 9-12
  121. protected void InitMppingInfo<T, T2, T3, T4, T5, T6, T7, T8, T9>()
  122. {
  123. InitMppingInfo<T, T2, T3, T4, T5, T6, T7, T8>();
  124. InitMppingInfo<T9>();
  125. }
  126. protected void InitMppingInfo<T, T2, T3, T4, T5, T6, T7, T8, T9, T10>()
  127. {
  128. InitMppingInfo<T, T2, T3, T4, T5, T6, T7, T8, T9>();
  129. InitMppingInfo<T10>();
  130. }
  131. protected void InitMppingInfo<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>()
  132. {
  133. InitMppingInfo<T, T2, T3, T4, T5, T6, T7, T8, T9, T10>();
  134. InitMppingInfo<T11>();
  135. }
  136. protected void InitMppingInfo<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>()
  137. {
  138. InitMppingInfo<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>();
  139. InitMppingInfo<T12>();
  140. }
  141. #endregion
  142. internal void InitMppingInfo<T>()
  143. {
  144. InitMppingInfo(typeof(T));
  145. }
  146. public void InitMppingInfo(Type type)
  147. {
  148. var cacheKey = "Context.InitAttributeMappingTables" + type.FullName;
  149. var entityInfo = this.Context.Utilities.GetReflectionInoCacheInstance().GetOrCreate<EntityInfo>(cacheKey,
  150. () =>
  151. {
  152. var result = this.Context.EntityMaintenance.GetEntityInfo(type);
  153. return result;
  154. });
  155. var copyObj = CopyEntityInfo(entityInfo);
  156. InitMppingInfo(copyObj);
  157. }
  158. private EntityInfo CopyEntityInfo(EntityInfo entityInfo)
  159. {
  160. var result = new EntityInfo
  161. {
  162. DbTableName = entityInfo.DbTableName,
  163. EntityName = entityInfo.EntityName,
  164. Type = entityInfo.Type
  165. };
  166. var columns = new List<EntityColumnInfo>();
  167. if (entityInfo.Columns.HasValue())
  168. {
  169. foreach (var item in entityInfo.Columns)
  170. {
  171. var column = new EntityColumnInfo
  172. {
  173. ColumnDescription = item.ColumnDescription,
  174. DataType = item.DataType,
  175. DbColumnName = item.DbColumnName,
  176. DbTableName = item.DbTableName,
  177. DecimalDigits = item.DecimalDigits,
  178. DefaultValue = item.DefaultValue,
  179. EntityName = item.EntityName,
  180. IsIdentity = item.IsIdentity,
  181. IsIgnore = item.IsIgnore,
  182. IsNullable = item.IsNullable,
  183. IsOnlyIgnoreInsert = item.IsOnlyIgnoreInsert,
  184. IsPrimarykey = item.IsPrimarykey,
  185. Length = item.Length,
  186. OldDbColumnName = item.OldDbColumnName,
  187. OracleSequenceName = item.OracleSequenceName,
  188. PropertyInfo = item.PropertyInfo,
  189. PropertyName = item.PropertyName
  190. };
  191. columns.Add(item);
  192. }
  193. }
  194. result.Columns = columns;
  195. return result;
  196. }
  197. private void InitMppingInfo(EntityInfo entityInfo)
  198. {
  199. if (this.Context.MappingTables == null)
  200. this.Context.MappingTables = new MappingTableList();
  201. if (this.Context.MappingColumns == null)
  202. this.Context.MappingColumns = new MappingColumnList();
  203. if (this.Context.IgnoreColumns == null)
  204. this.Context.IgnoreColumns = new IgnoreColumnList();
  205. if (this.Context.IgnoreInsertColumns == null)
  206. this.Context.IgnoreInsertColumns = new IgnoreColumnList();
  207. if (!this.Context.MappingTables.Any(it => it.EntityName == entityInfo.EntityName))
  208. {
  209. if (entityInfo.DbTableName != entityInfo.EntityName && entityInfo.DbTableName.HasValue())
  210. {
  211. this.Context.MappingTables.Add(entityInfo.EntityName, entityInfo.DbTableName);
  212. }
  213. }
  214. if (entityInfo.Columns.Any(it => it.EntityName == entityInfo.EntityName))
  215. {
  216. var mappingColumnInfos = this.Context.MappingColumns.Where(it => it.EntityName == entityInfo.EntityName);
  217. foreach (var item in entityInfo.Columns.Where(it => !it.IsIgnore))
  218. {
  219. if (!mappingColumnInfos.Any(it => it.PropertyName == item.PropertyName))
  220. if (item.PropertyName != item.DbColumnName && item.DbColumnName.HasValue())
  221. this.Context.MappingColumns.Add(item.PropertyName, item.DbColumnName, item.EntityName);
  222. }
  223. var ignoreInfos = this.Context.IgnoreColumns.Where(it => it.EntityName == entityInfo.EntityName);
  224. foreach (var item in entityInfo.Columns.Where(it => it.IsIgnore))
  225. {
  226. if (!ignoreInfos.Any(it => it.PropertyName == item.PropertyName))
  227. this.Context.IgnoreColumns.Add(item.PropertyName, item.EntityName);
  228. }
  229. var ignoreInsertInfos = this.Context.IgnoreInsertColumns.Where(it => it.EntityName == entityInfo.EntityName);
  230. foreach (var item in entityInfo.Columns.Where(it => it.IsOnlyIgnoreInsert))
  231. {
  232. if (!ignoreInsertInfos.Any(it => it.PropertyName == item.PropertyName))
  233. this.Context.IgnoreInsertColumns.Add(item.PropertyName, item.EntityName);
  234. }
  235. }
  236. }
  237. #endregion
  238. #region Create Instance
  239. protected ISugarQueryable<T> CreateQueryable<T>() where T : class, new()
  240. {
  241. var result = InstanceFactory.GetQueryable<T>(this.CurrentConnectionConfig);
  242. return CreateQueryable(result);
  243. }
  244. protected ISugarQueryable<T> CreateQueryable<T>(ISugarQueryable<T> result) where T : class, new()
  245. {
  246. var sqlBuilder = InstanceFactory.GetSqlbuilder(CurrentConnectionConfig);
  247. result.Context = this.Context;
  248. result.SqlBuilder = sqlBuilder;
  249. result.SqlBuilder.QueryBuilder = InstanceFactory.GetQueryBuilder(CurrentConnectionConfig);
  250. result.SqlBuilder.QueryBuilder.Builder = sqlBuilder;
  251. result.SqlBuilder.Context = result.SqlBuilder.QueryBuilder.Context = this.Context;
  252. result.SqlBuilder.QueryBuilder.EntityType = typeof(T);
  253. result.SqlBuilder.QueryBuilder.EntityName = typeof(T).Name;
  254. result.SqlBuilder.QueryBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(CurrentConnectionConfig);
  255. return result;
  256. }
  257. protected InsertableProvider<T> CreateInsertable<T>(T[] insertObjs) where T : class, new()
  258. {
  259. var result = InstanceFactory.GetInsertableProvider<T>(this.CurrentConnectionConfig);
  260. var sqlBuilder = InstanceFactory.GetSqlbuilder(this.CurrentConnectionConfig); ;
  261. result.Context = this.Context;
  262. result.EntityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>();
  263. result.SqlBuilder = sqlBuilder;
  264. result.InsertObjs = insertObjs;
  265. sqlBuilder.InsertBuilder = result.InsertBuilder = InstanceFactory.GetInsertBuilder(this.CurrentConnectionConfig);
  266. sqlBuilder.InsertBuilder.Builder = sqlBuilder;
  267. sqlBuilder.InsertBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.CurrentConnectionConfig);
  268. sqlBuilder.Context = result.SqlBuilder.InsertBuilder.Context = this.Context;
  269. result.Init();
  270. return result;
  271. }
  272. protected DeleteableProvider<T> CreateDeleteable<T>() where T : class, new()
  273. {
  274. var result = InstanceFactory.GetDeleteableProvider<T>(this.CurrentConnectionConfig);
  275. var sqlBuilder = InstanceFactory.GetSqlbuilder(this.CurrentConnectionConfig); ;
  276. result.Context = this.Context;
  277. result.SqlBuilder = sqlBuilder;
  278. sqlBuilder.DeleteBuilder = result.DeleteBuilder = InstanceFactory.GetDeleteBuilder(this.CurrentConnectionConfig);
  279. sqlBuilder.DeleteBuilder.Builder = sqlBuilder;
  280. sqlBuilder.DeleteBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.CurrentConnectionConfig);
  281. sqlBuilder.Context = result.SqlBuilder.DeleteBuilder.Context = this.Context;
  282. return result;
  283. }
  284. protected UpdateableProvider<T> CreateUpdateable<T>(T[] UpdateObjs) where T : class, new()
  285. {
  286. var result = InstanceFactory.GetUpdateableProvider<T>(this.CurrentConnectionConfig);
  287. var sqlBuilder = InstanceFactory.GetSqlbuilder(this.CurrentConnectionConfig); ;
  288. result.Context = this.Context;
  289. result.EntityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>();
  290. result.SqlBuilder = sqlBuilder;
  291. result.UpdateObjs = UpdateObjs;
  292. sqlBuilder.UpdateBuilder = result.UpdateBuilder = InstanceFactory.GetUpdateBuilder(this.CurrentConnectionConfig);
  293. sqlBuilder.UpdateBuilder.Builder = sqlBuilder;
  294. sqlBuilder.UpdateBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.CurrentConnectionConfig);
  295. sqlBuilder.Context = result.SqlBuilder.UpdateBuilder.Context = this.Context;
  296. result.Init();
  297. return result;
  298. }
  299. protected void CreateQueryJoin<T>(Expression joinExpression, Type[] types, ISugarQueryable<T> queryable) where T : class, new()
  300. {
  301. this.CreateQueryable<T>(queryable);
  302. var shortName = string.Empty;
  303. var paramters = new List<SugarParameter>();
  304. queryable.SqlBuilder.QueryBuilder.JoinQueryInfos = this.GetJoinInfos(queryable.SqlBuilder, joinExpression, ref paramters, ref shortName, types);
  305. queryable.SqlBuilder.QueryBuilder.TableShortName = shortName;
  306. if (paramters != null)
  307. {
  308. queryable.SqlBuilder.QueryBuilder.Parameters.AddRange(paramters);
  309. }
  310. }
  311. protected void CreateEasyQueryJoin<T>(Expression joinExpression, Type[] types, ISugarQueryable<T> queryable) where T : class, new()
  312. {
  313. this.CreateQueryable<T>(queryable);
  314. var shortName = string.Empty;
  315. queryable.SqlBuilder.QueryBuilder.EasyJoinInfos = this.GetEasyJoinInfo(joinExpression, ref shortName, queryable.SqlBuilder, types);
  316. queryable.SqlBuilder.QueryBuilder.TableShortName = shortName;
  317. }
  318. #endregion
  319. #region Private methods
  320. protected List<JoinQueryInfo> GetJoinInfos(ISqlBuilder sqlBuilder, Expression joinExpression, ref List<SugarParameter> parameters, ref string shortName, params Type[] entityTypeArray)
  321. {
  322. var result = new List<JoinQueryInfo>();
  323. var lambdaParameters = ((LambdaExpression)joinExpression).Parameters.ToList();
  324. var expressionContext = sqlBuilder.QueryBuilder.LambdaExpressions;
  325. expressionContext.MappingColumns = this.Context.MappingColumns;
  326. expressionContext.MappingTables = this.Context.MappingTables;
  327. expressionContext.Resolve(joinExpression, ResolveExpressType.Join);
  328. var i = 0;
  329. var joinArray = MergeJoinArray(expressionContext.Result.GetResultArray());
  330. parameters = expressionContext.Parameters;
  331. foreach (var entityType in entityTypeArray)
  332. {
  333. var isFirst = i == 0; ++i;
  334. var joinInfo = new JoinQueryInfo();
  335. var hasMappingTable = expressionContext.MappingTables.HasValue();
  336. MappingTable mappingInfo = null;
  337. if (hasMappingTable)
  338. {
  339. mappingInfo = expressionContext.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityType.Name, StringComparison.CurrentCultureIgnoreCase));
  340. joinInfo.TableName = mappingInfo != null ? mappingInfo.DbTableName : entityType.Name;
  341. }
  342. else
  343. {
  344. joinInfo.TableName = entityType.Name;
  345. }
  346. if (isFirst)
  347. {
  348. var firstItem = lambdaParameters.First();
  349. lambdaParameters.Remove(firstItem);
  350. shortName = firstItem.Name;
  351. }
  352. var joinString = joinArray[i * 2 - 2];
  353. joinInfo.ShortName = lambdaParameters[i - 1].Name;
  354. joinInfo.JoinType = (JoinType)Enum.Parse(typeof(JoinType), joinString);
  355. joinInfo.JoinWhere = joinArray[i * 2 - 1];
  356. joinInfo.JoinIndex = i;
  357. result.Add((joinInfo));
  358. }
  359. expressionContext.Clear();
  360. return result;
  361. }
  362. private string[] MergeJoinArray(string[] joinArray)
  363. {
  364. var result = new List<string>();
  365. string joinValue = null;
  366. var i = 0;
  367. foreach (var item in joinArray)
  368. {
  369. ++i;
  370. var isLast = joinArray.Length == i;
  371. var isJoinType = item.IsIn(JoinType.Inner.ToString(), JoinType.Left.ToString(), JoinType.Right.ToString());
  372. if (isJoinType)
  373. {
  374. if (joinValue != null)
  375. result.Add(joinValue);
  376. joinValue = null;
  377. result.Add(item);
  378. }
  379. else
  380. {
  381. isJoinType = false;
  382. joinValue += joinValue == null ? item : ("," + item);
  383. }
  384. if (isLast)
  385. {
  386. result.Add(joinValue);
  387. }
  388. }
  389. return result.ToArray(); ;
  390. }
  391. protected Dictionary<string, string> GetEasyJoinInfo(Expression joinExpression, ref string shortName, ISqlBuilder builder, params Type[] entityTypeArray)
  392. {
  393. var result = new Dictionary<string, string>();
  394. var lambdaParameters = ((LambdaExpression)joinExpression).Parameters.ToList();
  395. shortName = lambdaParameters.First().Name;
  396. var index = 1;
  397. foreach (var item in entityTypeArray)
  398. {
  399. result.Add(UtilConstants.Space + lambdaParameters[index].Name, item.Name);
  400. ++index;
  401. }
  402. return result;
  403. }
  404. #endregion
  405. }
  406. }