InsertableProvider.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. using System.Reflection;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace SqlSugar
  11. {
  12. public partial class InsertableProvider<T> : IInsertable<T> where T : class, new()
  13. {
  14. public SqlSugarProvider Context { get; set; }
  15. public IAdo Ado { get { return Context.Ado; } }
  16. public ISqlBuilder SqlBuilder { get; set; }
  17. public InsertBuilder InsertBuilder { get; set; }
  18. public bool IsMappingTable { get { return this.Context.MappingTables != null && this.Context.MappingTables.Any(); } }
  19. public bool IsMappingColumns { get { return this.Context.MappingColumns != null && this.Context.MappingColumns.Any(); } }
  20. public bool IsSingle { get { return this.InsertObjs.Length == 1; } }
  21. public EntityInfo EntityInfo { get; set; }
  22. public List<MappingColumn> MappingColumnList { get; set; }
  23. private List<string> IgnoreColumnNameList { get; set; }
  24. internal bool IsOffIdentity { get; set; }
  25. public T[] InsertObjs { get; set; }
  26. public MappingTableList OldMappingTableList { get; set; }
  27. public bool IsAs { get; set; }
  28. public bool IsEnableDiffLogEvent { get; set; }
  29. public DiffLogModel diffModel { get; set; }
  30. internal Action RemoveCacheFunc { get; set; }
  31. #region Core
  32. public void AddQueue()
  33. {
  34. if (this.InsertObjs != null && this.InsertObjs.Length > 0 && this.InsertObjs[0] != null)
  35. {
  36. var sqlObj = this.ToSql();
  37. this.Context.Queues.Add(sqlObj.Key, sqlObj.Value);
  38. }
  39. }
  40. public virtual int ExecuteCommand()
  41. {
  42. if (this.InsertObjs.Count() == 1 && this.InsertObjs.First() == null)
  43. {
  44. return 0;
  45. }
  46. string sql = _ExecuteCommand();
  47. var result = Ado.ExecuteCommand(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  48. After(sql, null);
  49. if (result == -1) return this.InsertObjs.Count();
  50. return result;
  51. }
  52. public virtual string ToSqlString()
  53. {
  54. var sqlObj = this.ToSql();
  55. var result = sqlObj.Key;
  56. if (result == null) return null;
  57. result = UtilMethods.GetSqlString(this.Context.CurrentConnectionConfig, sqlObj);
  58. return result;
  59. }
  60. public virtual KeyValuePair<string, List<SugarParameter>> ToSql()
  61. {
  62. InsertBuilder.IsReturnIdentity = true;
  63. PreToSql();
  64. AutoRemoveDataCache();
  65. string sql = InsertBuilder.ToSqlString();
  66. RestoreMapping();
  67. return new KeyValuePair<string, List<SugarParameter>>(sql, InsertBuilder.Parameters);
  68. }
  69. public async Task<List<Type>> ExecuteReturnPkListAsync<Type>()
  70. {
  71. return await Task.Run(() => ExecuteReturnPkList<Type>());
  72. }
  73. public virtual List<Type> ExecuteReturnPkList<Type>()
  74. {
  75. var pkInfo = this.EntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey == true);
  76. Check.ExceptionEasy(pkInfo == null, "ExecuteReturnPkList need primary key", "ExecuteReturnPkList需要主键");
  77. Check.ExceptionEasy(this.EntityInfo.Columns.Count(it => it.IsPrimarykey == true) > 1, "ExecuteReturnPkList ,Only support technology single primary key", "ExecuteReturnPkList只支技单主键");
  78. var isIdEntity = pkInfo.IsIdentity || (pkInfo.OracleSequenceName.HasValue() && this.Context.CurrentConnectionConfig.DbType == DbType.Oracle);
  79. if (isIdEntity && this.InsertObjs.Length == 1)
  80. {
  81. return InsertPkListIdentityCount1<Type>(pkInfo);
  82. }
  83. else if (isIdEntity && this.InsertBuilder.ConvertInsertReturnIdFunc == null)
  84. {
  85. return InsertPkListNoFunc<Type>(pkInfo);
  86. }
  87. else if (isIdEntity && this.InsertBuilder.ConvertInsertReturnIdFunc != null)
  88. {
  89. return InsertPkListWithFunc<Type>(pkInfo);
  90. }
  91. else if (pkInfo.UnderType == UtilConstants.LongType)
  92. {
  93. return InsertPkListLong<Type>();
  94. }
  95. else
  96. {
  97. return InsertPkListGuid<Type>(pkInfo);
  98. }
  99. }
  100. public virtual int ExecuteReturnIdentity()
  101. {
  102. if (this.InsertObjs.Count() == 1 && this.InsertObjs.First() == null)
  103. {
  104. return 0;
  105. }
  106. string sql = _ExecuteReturnIdentity();
  107. var result = 0;
  108. if (InsertBuilder.IsOleDb)
  109. {
  110. var isAuto = false;
  111. if (this.Context.Ado.IsAnyTran() == false && this.Context.CurrentConnectionConfig.IsAutoCloseConnection)
  112. {
  113. isAuto = this.Context.CurrentConnectionConfig.IsAutoCloseConnection;
  114. this.Context.CurrentConnectionConfig.IsAutoCloseConnection = false;
  115. }
  116. result = Ado.GetInt(sql.Split(';').First(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  117. result = Ado.GetInt(sql.Split(';').Last(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  118. if (this.Context.Ado.IsAnyTran() == false && isAuto)
  119. {
  120. this.Ado.Close();
  121. this.Context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
  122. }
  123. }
  124. else
  125. {
  126. result = Ado.GetInt(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  127. }
  128. After(sql, result);
  129. return result;
  130. }
  131. public virtual long ExecuteReturnBigIdentity()
  132. {
  133. if (this.InsertObjs.Count() == 1 && this.InsertObjs.First() == null)
  134. {
  135. return 0;
  136. }
  137. string sql = _ExecuteReturnBigIdentity();
  138. long result = 0;
  139. if (InsertBuilder.IsOleDb)
  140. {
  141. var isAuto = false;
  142. if (this.Context.Ado.IsAnyTran() == false && this.Context.CurrentConnectionConfig.IsAutoCloseConnection)
  143. {
  144. isAuto = this.Context.CurrentConnectionConfig.IsAutoCloseConnection;
  145. this.Context.CurrentConnectionConfig.IsAutoCloseConnection = false;
  146. }
  147. result = Convert.ToInt64(Ado.GetScalar(sql.Split(';').First(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()));
  148. result = Convert.ToInt64(Ado.GetScalar(sql.Split(';').Last(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()));
  149. if (this.Context.Ado.IsAnyTran() == false && isAuto)
  150. {
  151. this.Ado.Close();
  152. this.Context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
  153. }
  154. }
  155. else
  156. {
  157. result = Convert.ToInt64(Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()));
  158. }
  159. After(sql, result);
  160. return result;
  161. }
  162. public virtual long ExecuteReturnSnowflakeId()
  163. {
  164. if (this.InsertObjs.Length > 1)
  165. {
  166. return this.ExecuteReturnSnowflakeIdList().First();
  167. }
  168. var id = SnowFlakeSingle.instance.getID();
  169. var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  170. var snowProperty = entity.Columns.FirstOrDefault(it => it.IsPrimarykey && it.PropertyInfo.PropertyType == UtilConstants.LongType);
  171. Check.Exception(snowProperty == null, "The entity sets the primary key and is long");
  172. Check.Exception(snowProperty.IsIdentity == true, "SnowflakeId IsIdentity can't true");
  173. foreach (var item in this.InsertBuilder.DbColumnInfoList.Where(it => it.PropertyName == snowProperty.PropertyName))
  174. {
  175. item.Value = id;
  176. snowProperty?.PropertyInfo.SetValue(this.InsertObjs.First(), id);
  177. }
  178. this.ExecuteCommand();
  179. return id;
  180. }
  181. public List<long> ExecuteReturnSnowflakeIdList()
  182. {
  183. List<long> result = new List<long>();
  184. var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  185. var snowProperty = entity.Columns.FirstOrDefault(it => it.IsPrimarykey && it.PropertyInfo.PropertyType == UtilConstants.LongType);
  186. Check.Exception(snowProperty == null, "The entity sets the primary key and is long");
  187. Check.Exception(snowProperty.IsIdentity == true, "SnowflakeId IsIdentity can't true");
  188. foreach (var item in this.InsertBuilder.DbColumnInfoList.Where(it => it.PropertyName == snowProperty.PropertyName))
  189. {
  190. var id = SnowFlakeSingle.instance.getID();
  191. item.Value = id;
  192. result.Add(id);
  193. var obj = this.InsertObjs.ElementAtOrDefault(item.TableId);
  194. if (obj != null)
  195. {
  196. snowProperty?.PropertyInfo.SetValue(obj, id);
  197. }
  198. }
  199. this.ExecuteCommand();
  200. return result;
  201. }
  202. public Task<long> ExecuteReturnSnowflakeIdAsync(CancellationToken token)
  203. {
  204. this.Context.Ado.CancellationToken= token;
  205. return ExecuteReturnSnowflakeIdAsync();
  206. }
  207. public async Task<long> ExecuteReturnSnowflakeIdAsync()
  208. {
  209. var id = SnowFlakeSingle.instance.getID();
  210. var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  211. var snowProperty = entity.Columns.FirstOrDefault(it => it.IsPrimarykey && it.PropertyInfo.PropertyType == UtilConstants.LongType);
  212. Check.Exception(snowProperty == null, "The entity sets the primary key and is long");
  213. Check.Exception(snowProperty.IsIdentity == true, "SnowflakeId IsIdentity can't true");
  214. foreach (var item in this.InsertBuilder.DbColumnInfoList.Where(it => it.PropertyName == snowProperty.PropertyName))
  215. {
  216. item.Value = id;
  217. snowProperty?.PropertyInfo.SetValue(this.InsertObjs.First(), id);
  218. }
  219. await this.ExecuteCommandAsync();
  220. return id;
  221. }
  222. public async Task<List<long>> ExecuteReturnSnowflakeIdListAsync()
  223. {
  224. List<long> result = new List<long>();
  225. var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  226. var snowProperty = entity.Columns.FirstOrDefault(it => it.IsPrimarykey && it.PropertyInfo.PropertyType == UtilConstants.LongType);
  227. Check.Exception(snowProperty == null, "The entity sets the primary key and is long");
  228. Check.Exception(snowProperty.IsIdentity == true, "SnowflakeId IsIdentity can't true");
  229. foreach (var item in this.InsertBuilder.DbColumnInfoList.Where(it => it.PropertyName == snowProperty.PropertyName))
  230. {
  231. var id = SnowFlakeSingle.instance.getID();
  232. item.Value = id;
  233. result.Add(id);
  234. var obj = this.InsertObjs.ElementAtOrDefault(item.TableId);
  235. if (obj != null)
  236. {
  237. snowProperty?.PropertyInfo.SetValue(obj, id);
  238. }
  239. }
  240. await this.ExecuteCommandAsync();
  241. return result;
  242. }
  243. public Task<List<long>> ExecuteReturnSnowflakeIdListAsync(CancellationToken token)
  244. {
  245. this.Ado.CancellationToken= token;
  246. return ExecuteReturnSnowflakeIdListAsync();
  247. }
  248. public virtual T ExecuteReturnEntity()
  249. {
  250. ExecuteCommandIdentityIntoEntity();
  251. return InsertObjs.First();
  252. }
  253. public virtual bool ExecuteCommandIdentityIntoEntity()
  254. {
  255. var result = InsertObjs.First();
  256. var identityKeys = GetIdentityKeys();
  257. if (identityKeys.Count == 0)
  258. {
  259. var snowColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey && it.UnderType == UtilConstants.LongType);
  260. if (snowColumn!=null)
  261. {
  262. if (Convert.ToInt64(snowColumn.PropertyInfo.GetValue(result)) == 0)
  263. {
  264. var id = this.ExecuteReturnSnowflakeId();
  265. snowColumn.PropertyInfo.SetValue(result, id);
  266. }
  267. else
  268. {
  269. ExecuteCommand();
  270. }
  271. return true;
  272. }
  273. else
  274. {
  275. return this.ExecuteCommand() > 0;
  276. }
  277. }
  278. var idValue = ExecuteReturnBigIdentity();
  279. Check.Exception(identityKeys.Count > 1, "ExecuteCommandIdentityIntoEntity does not support multiple identity keys");
  280. var identityKey = identityKeys.First();
  281. object setValue = 0;
  282. if (idValue > int.MaxValue)
  283. setValue = idValue;
  284. else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(uint)))
  285. {
  286. setValue = Convert.ToUInt32(idValue);
  287. }
  288. else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(ulong)))
  289. {
  290. setValue = Convert.ToUInt64(idValue);
  291. }
  292. else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(ushort)))
  293. {
  294. setValue = Convert.ToUInt16(idValue);
  295. }
  296. else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(short)))
  297. {
  298. setValue = Convert.ToInt16(idValue);
  299. }
  300. else
  301. setValue = Convert.ToInt32(idValue);
  302. this.Context.EntityMaintenance.GetProperty<T>(identityKey).SetValue(result, setValue, null);
  303. return idValue > 0;
  304. }
  305. public Task<int> ExecuteCommandAsync(CancellationToken token)
  306. {
  307. this.Context.Ado.CancellationToken= token;
  308. return ExecuteCommandAsync();
  309. }
  310. public async Task<int> ExecuteCommandAsync()
  311. {
  312. if (this.InsertObjs.Count() == 1 && this.InsertObjs.First() == null)
  313. {
  314. return 0;
  315. }
  316. string sql = _ExecuteCommand();
  317. var result =await Ado.ExecuteCommandAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  318. After(sql, null);
  319. if (result == -1) return this.InsertObjs.Count();
  320. return result;
  321. }
  322. public Task<int> ExecuteReturnIdentityAsync(CancellationToken token)
  323. {
  324. this.Ado.CancellationToken= token;
  325. return ExecuteReturnIdentityAsync();
  326. }
  327. public virtual async Task<int> ExecuteReturnIdentityAsync()
  328. {
  329. if (this.InsertObjs.Count() == 1 && this.InsertObjs.First() == null)
  330. {
  331. return 0;
  332. }
  333. string sql = _ExecuteReturnIdentity();
  334. var result = 0;
  335. if (InsertBuilder.IsOleDb)
  336. {
  337. var isAuto = false;
  338. if (this.Context.Ado.IsAnyTran() == false && this.Context.CurrentConnectionConfig.IsAutoCloseConnection)
  339. {
  340. isAuto = this.Context.CurrentConnectionConfig.IsAutoCloseConnection;
  341. this.Context.CurrentConnectionConfig.IsAutoCloseConnection = false;
  342. }
  343. result = Ado.GetInt(sql.Split(';').First(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  344. result = Ado.GetInt(sql.Split(';').Last(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  345. if (this.Context.Ado.IsAnyTran() == false && isAuto)
  346. {
  347. this.Ado.Close();
  348. this.Context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
  349. }
  350. }
  351. else
  352. {
  353. result = await Ado.GetIntAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  354. }
  355. After(sql, result);
  356. return result;
  357. }
  358. public T ExecuteReturnEntity(bool isIncludesAllFirstLayer)
  359. {
  360. var data = ExecuteReturnEntity();
  361. if (this.InsertBuilder.IsWithAttr)
  362. {
  363. return this.Context.Root.QueryableWithAttr<T>().WhereClassByPrimaryKey(data).IncludesAllFirstLayer().First();
  364. }
  365. else
  366. {
  367. return this.Context.Queryable<T>().WhereClassByPrimaryKey(data).IncludesAllFirstLayer().First();
  368. }
  369. }
  370. public async Task<T> ExecuteReturnEntityAsync()
  371. {
  372. await ExecuteCommandIdentityIntoEntityAsync();
  373. return InsertObjs.First();
  374. }
  375. public async Task<T> ExecuteReturnEntityAsync(bool isIncludesAllFirstLayer)
  376. {
  377. var data = await ExecuteReturnEntityAsync();
  378. if (this.InsertBuilder.IsWithAttr)
  379. {
  380. return await this.Context.Root.QueryableWithAttr<T>().WhereClassByPrimaryKey(data).IncludesAllFirstLayer().FirstAsync();
  381. }
  382. else
  383. {
  384. return await this.Context.Queryable<T>().WhereClassByPrimaryKey(data).IncludesAllFirstLayer().FirstAsync();
  385. }
  386. }
  387. public async Task<bool> ExecuteCommandIdentityIntoEntityAsync()
  388. {
  389. var result = InsertObjs.First();
  390. var identityKeys = GetIdentityKeys();
  391. if (identityKeys.Count == 0)
  392. {
  393. var snowColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey&& it.UnderType == UtilConstants.LongType);
  394. if (snowColumn != null)
  395. {
  396. if (Convert.ToInt64(snowColumn.PropertyInfo.GetValue(result)) == 0)
  397. {
  398. var id = await this.ExecuteReturnSnowflakeIdAsync();
  399. snowColumn.PropertyInfo.SetValue(result, id);
  400. }
  401. else
  402. {
  403. await this.ExecuteCommandAsync();
  404. }
  405. return true;
  406. }
  407. else
  408. {
  409. return await this.ExecuteCommandAsync() > 0;
  410. }
  411. }
  412. var idValue =await ExecuteReturnBigIdentityAsync();
  413. Check.Exception(identityKeys.Count > 1, "ExecuteCommandIdentityIntoEntity does not support multiple identity keys");
  414. var identityKey = identityKeys.First();
  415. object setValue = 0;
  416. if (idValue > int.MaxValue)
  417. setValue = idValue;
  418. else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(uint)))
  419. {
  420. setValue = Convert.ToUInt32(idValue);
  421. }
  422. else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(ulong)))
  423. {
  424. setValue = Convert.ToUInt64(idValue);
  425. }
  426. else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(ushort)))
  427. {
  428. setValue = Convert.ToUInt16(idValue);
  429. }
  430. else if (this.EntityInfo.Columns.Any(it => it.IsIdentity && it.PropertyInfo.PropertyType == typeof(short)))
  431. {
  432. setValue = Convert.ToInt16(idValue);
  433. }
  434. else
  435. setValue = Convert.ToInt32(idValue);
  436. this.Context.EntityMaintenance.GetProperty<T>(identityKey).SetValue(result, setValue, null);
  437. return idValue > 0;
  438. }
  439. public Task<long> ExecuteReturnBigIdentityAsync(CancellationToken token)
  440. {
  441. this.Context.Ado.CancellationToken= token;
  442. return ExecuteReturnBigIdentityAsync();
  443. }
  444. public virtual async Task<long> ExecuteReturnBigIdentityAsync()
  445. {
  446. if (this.InsertObjs.Count() == 1 && this.InsertObjs.First() == null)
  447. {
  448. return 0;
  449. }
  450. string sql = _ExecuteReturnBigIdentity();
  451. long result = 0;
  452. if (InsertBuilder.IsOleDb)
  453. {
  454. var isAuto = false;
  455. if (this.Context.Ado.IsAnyTran() == false && this.Context.CurrentConnectionConfig.IsAutoCloseConnection)
  456. {
  457. isAuto = this.Context.CurrentConnectionConfig.IsAutoCloseConnection;
  458. this.Context.CurrentConnectionConfig.IsAutoCloseConnection = false;
  459. }
  460. result = Ado.GetInt(sql.Split(';').First(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  461. result = Ado.GetInt(sql.Split(';').Last(), InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  462. if (this.Context.Ado.IsAnyTran() == false && isAuto)
  463. {
  464. this.Ado.Close();
  465. this.Context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
  466. }
  467. }
  468. else
  469. {
  470. result = Convert.ToInt64(await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()));
  471. }
  472. After(sql, result);
  473. return result;
  474. }
  475. #endregion
  476. #region Setting
  477. public InsertablePage<T> PageSize(int pageSize)
  478. {
  479. InsertablePage<T> result = new InsertablePage<T>();
  480. result.PageSize = pageSize;
  481. result.Context = this.Context;
  482. result.DataList = this.InsertObjs;
  483. result.TableName = this.InsertBuilder.AsName;
  484. result.IsEnableDiffLogEvent = this.IsEnableDiffLogEvent;
  485. result.DiffModel = this.diffModel;
  486. result.IsOffIdentity = this.InsertBuilder.IsOffIdentity;
  487. if(this.InsertBuilder.DbColumnInfoList.Any())
  488. result.InsertColumns = this.InsertBuilder.DbColumnInfoList.GroupBy(it => it.TableId).First().Select(it=>it.DbColumnName).ToList();
  489. return result;
  490. }
  491. public IParameterInsertable<T> UseParameter()
  492. {
  493. var result = new ParameterInsertable<T>();
  494. result.Context= this.Context;
  495. result.Inserable = this;
  496. return result;
  497. }
  498. public IInsertable<T> AsType(Type tableNameType)
  499. {
  500. return AS(this.Context.EntityMaintenance.GetEntityInfo(tableNameType).DbTableName);
  501. }
  502. public IInsertable<T> AS(string tableName)
  503. {
  504. this.InsertBuilder.AsName = tableName;
  505. return this; ;
  506. }
  507. public IInsertable<T> IgnoreColumns(Expression<Func<T, object>> columns)
  508. {
  509. if (columns == null) return this;
  510. var ignoreColumns = InsertBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it)).ToList();
  511. this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => !ignoreColumns.Any(ig => ig.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase))).ToList();
  512. this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => !ignoreColumns.Any(ig => ig.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList();
  513. return this;
  514. }
  515. public IInsertable<T> IgnoreColumns(params string[] columns)
  516. {
  517. if (columns == null)
  518. columns = new string[] { };
  519. this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => !columns.Any(ig => ig.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase))).ToList();
  520. this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => !columns.Any(ig => ig.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList();
  521. return this;
  522. }
  523. public IInsertable<T> IgnoreColumnsNull(bool isIgnoreNull = true)
  524. {
  525. if (isIgnoreNull)
  526. {
  527. Check.Exception(this.InsertObjs.Count() > 1 , ErrorMessage.GetThrowMessage("ignoreNullColumn NoSupport batch insert, use .PageSize(1).IgnoreColumnsNull().ExecuteCommand()", "ignoreNullColumn 不支持批量操作,你可以用PageSzie(1).IgnoreColumnsNull().ExecuteCommand()"));
  528. this.InsertBuilder.IsNoInsertNull = true;
  529. }
  530. return this;
  531. }
  532. public IInsertable<T> MySqlIgnore()
  533. {
  534. this.InsertBuilder.MySqlIgnore = true;
  535. return this;
  536. }
  537. public IInsertable<T> InsertColumns(Expression<Func<T, object>> columns)
  538. {
  539. if (columns == null) return this;
  540. var ignoreColumns = InsertBuilder.GetExpressionValue(columns, ResolveExpressType.ArraySingle).GetResultArray().Select(it => this.SqlBuilder.GetNoTranslationColumnName(it)).ToList();
  541. this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => ignoreColumns.Any(ig => ig.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)) || ignoreColumns.Any(ig => ig.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList();
  542. return this;
  543. }
  544. public IInsertable<T> InsertColumns(string[] columns)
  545. {
  546. if (columns == null) return this;
  547. this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => columns.Any(ig => ig.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase))|| columns.Any(ig => ig.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))).ToList();
  548. return this;
  549. }
  550. public IInsertable<T> With(string lockString)
  551. {
  552. if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer)
  553. this.InsertBuilder.TableWithString = lockString;
  554. return this;
  555. }
  556. public IInsertable<T> OffIdentity(bool isSetOn)
  557. {
  558. if (isSetOn)
  559. {
  560. return this.OffIdentity();
  561. }
  562. else
  563. {
  564. return this;
  565. }
  566. }
  567. public IInsertable<T> OffIdentity()
  568. {
  569. this.IsOffIdentity = true;
  570. this.InsertBuilder.IsOffIdentity = true;
  571. return this;
  572. }
  573. public IInsertable<T> IgnoreColumns(bool ignoreNullColumn, bool isOffIdentity = false) {
  574. Check.Exception(this.InsertObjs.Count() > 1&& ignoreNullColumn, ErrorMessage.GetThrowMessage("ignoreNullColumn NoSupport batch insert, use .PageSize(1).IgnoreColumnsNull().ExecuteCommand()", "ignoreNullColumn 不支持批量操作, 你可以使用 .PageSize(1).IgnoreColumnsNull().ExecuteCommand()"));
  575. this.IsOffIdentity = isOffIdentity;
  576. this.InsertBuilder.IsOffIdentity = isOffIdentity;
  577. if (this.InsertBuilder.LambdaExpressions == null)
  578. this.InsertBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(this.Context.CurrentConnectionConfig);
  579. this.InsertBuilder.IsNoInsertNull = ignoreNullColumn;
  580. return this;
  581. }
  582. public IInsertable<T> RemoveDataCache()
  583. {
  584. this.RemoveCacheFunc = () =>
  585. {
  586. var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService;
  587. CacheSchemeMain.RemoveCache(cacheService, this.Context.EntityMaintenance.GetTableName<T>());
  588. };
  589. return this;
  590. }
  591. public IInsertable<T> RemoveDataCache(string likeString)
  592. {
  593. this.RemoveCacheFunc = () =>
  594. {
  595. var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService;
  596. CacheSchemeMain.RemoveCacheByLike(cacheService, likeString);
  597. };
  598. return this;
  599. }
  600. public MySqlBlukCopy<T> UseMySql()
  601. {
  602. return new MySqlBlukCopy<T>(this.Context, this.SqlBuilder, InsertObjs);
  603. }
  604. public SqlServerBlukCopy UseSqlServer()
  605. {
  606. PreToSql();
  607. var currentType = this.Context.CurrentConnectionConfig.DbType;
  608. Check.Exception(currentType != DbType.SqlServer, "UseSqlServer no support " + currentType);
  609. SqlServerBlukCopy result = new SqlServerBlukCopy();
  610. result.DbColumnInfoList =this.InsertBuilder.DbColumnInfoList.GroupBy(it => it.TableId).ToList();
  611. result.InsertBuilder = this.InsertBuilder;
  612. result.Builder = this.SqlBuilder;
  613. result.Context = this.Context;
  614. result.Inserts=this.InsertObjs;
  615. return result;
  616. }
  617. public OracleBlukCopy UseOracle()
  618. {
  619. PreToSql();
  620. var currentType = this.Context.CurrentConnectionConfig.DbType;
  621. Check.Exception(currentType != DbType.Oracle, "UseSqlServer no support " + currentType);
  622. OracleBlukCopy result = new OracleBlukCopy();
  623. result.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.GroupBy(it => it.TableId).ToList();
  624. result.InsertBuilder = this.InsertBuilder;
  625. result.Builder = this.SqlBuilder;
  626. result.Context = this.Context;
  627. result.Inserts = this.InsertObjs;
  628. InsertBuilder.IsBlukCopy = true;
  629. return result;
  630. }
  631. public IInsertable<T> EnableDiffLogEventIF(bool isDiffLogEvent, object diffLogBizData)
  632. {
  633. if (isDiffLogEvent)
  634. {
  635. return EnableDiffLogEvent(diffLogBizData);
  636. }
  637. return this;
  638. }
  639. public IInsertable<T> EnableDiffLogEvent(object businessData = null)
  640. {
  641. //Check.Exception(this.InsertObjs.HasValue() && this.InsertObjs.Count() > 1, "DiffLog does not support batch operations");
  642. diffModel = new DiffLogModel();
  643. this.IsEnableDiffLogEvent = true;
  644. diffModel.BusinessData = businessData;
  645. diffModel.DiffType = DiffType.insert;
  646. return this;
  647. }
  648. public ISubInsertable<T> AddSubList(Expression<Func<T, object>> items)
  649. {
  650. Check.Exception(GetPrimaryKeys().Count == 0, typeof(T).Name + " need Primary key");
  651. Check.Exception(GetPrimaryKeys().Count > 1, typeof(T).Name + "Multiple primary keys are not supported");
  652. //Check.Exception(this.InsertObjs.Count() > 1, "SubInserable No Support Insertable(List<T>)");
  653. //Check.Exception(items.ToString().Contains(".First().")==false, items.ToString()+ " not supported ");
  654. if (this.InsertObjs == null || this.InsertObjs.Count() == 0)
  655. {
  656. return new SubInsertable<T>();
  657. }
  658. SubInsertable<T> result = new SubInsertable<T>();
  659. result.InsertObjects = this.InsertObjs;
  660. result.Context = this.Context;
  661. result.SubList = new List<SubInsertTreeExpression>();
  662. result.SubList.Add(new SubInsertTreeExpression() { Expression= items });
  663. result.InsertBuilder = this.InsertBuilder;
  664. result.Pk = GetPrimaryKeys().First();
  665. result.Entity = this.EntityInfo;
  666. return result;
  667. }
  668. public ISubInsertable<T> AddSubList(Expression<Func<T, SubInsertTree>> tree)
  669. {
  670. Check.Exception(GetPrimaryKeys().Count == 0, typeof(T).Name + " need Primary key");
  671. Check.Exception(GetPrimaryKeys().Count > 1, typeof(T).Name + "Multiple primary keys are not supported");
  672. //Check.Exception(this.InsertObjs.Count() > 1, "SubInserable No Support Insertable(List<T>)");
  673. //Check.Exception(items.ToString().Contains(".First().")==false, items.ToString()+ " not supported ");
  674. if (this.InsertObjs == null || this.InsertObjs.Count() == 0)
  675. {
  676. return new SubInsertable<T>();
  677. }
  678. SubInsertable<T> result = new SubInsertable<T>();
  679. result.InsertObjects = this.InsertObjs;
  680. result.Context = this.Context;
  681. result.SubList = new List<SubInsertTreeExpression>();
  682. result.InsertBuilder = this.InsertBuilder;
  683. result.Pk = GetPrimaryKeys().First();
  684. result.Entity = this.EntityInfo;
  685. result.AddSubList(tree);
  686. return result;
  687. }
  688. public SplitInsertable<T> SplitTable(SplitType splitType)
  689. {
  690. UtilMethods.StartCustomSplitTable(this.Context, typeof(T));
  691. SplitTableContext helper = new SplitTableContext(Context)
  692. {
  693. EntityInfo = this.EntityInfo
  694. };
  695. helper.CheckPrimaryKey();
  696. SplitInsertable<T> result = new SplitInsertable<T>();
  697. result.Context = this.Context;
  698. result.EntityInfo = this.EntityInfo;
  699. result.Helper = helper;
  700. result.SplitType = splitType;
  701. result.TableNames = new List<KeyValuePair<string, object>>();
  702. foreach (var item in this.InsertObjs)
  703. {
  704. var splitFieldValue = helper.GetValue(splitType, item);
  705. var tableName=helper.GetTableName(splitType, splitFieldValue);
  706. result.TableNames.Add(new KeyValuePair<string, object>(tableName,item));
  707. }
  708. result.Inserable = this;
  709. return result;
  710. }
  711. public SplitInsertable<T> SplitTable()
  712. {
  713. UtilMethods.StartCustomSplitTable(this.Context, typeof(T));
  714. var splitTableAttribute = typeof(T).GetCustomAttribute<SplitTableAttribute>();
  715. if (splitTableAttribute != null)
  716. {
  717. return SplitTable((splitTableAttribute as SplitTableAttribute).SplitType);
  718. }
  719. else
  720. {
  721. Check.Exception(true,$" {typeof(T).Name} need SplitTableAttribute");
  722. return null;
  723. }
  724. }
  725. #endregion
  726. }
  727. }