QueryableExecuteSqlAsync.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Linq;
  6. using System.Linq.Expressions;
  7. using System.Text;
  8. using System.Text.RegularExpressions;
  9. using System.Reflection;
  10. using System.Dynamic;
  11. using System.Threading.Tasks;
  12. using System.Threading;
  13. namespace SqlSugar
  14. {
  15. public partial class QueryableProvider<T> : QueryableAccessory, ISugarQueryable<T>
  16. {
  17. public async virtual Task<T[]> ToArrayAsync()
  18. {
  19. var result = await this.ToListAsync();
  20. if (result.HasValue())
  21. return result.ToArray();
  22. else
  23. return null;
  24. }
  25. public virtual async Task<T> InSingleAsync(object pkValue)
  26. {
  27. if (pkValue == null)
  28. {
  29. return default(T);
  30. }
  31. Check.Exception(this.QueryBuilder.SelectValue.HasValue(), "'InSingle' and' Select' can't be used together,You can use .Select(it=>...).Single(it.id==1)");
  32. var list = await In(pkValue).ToListAsync();
  33. if (list == null) return default(T);
  34. else return list.SingleOrDefault();
  35. }
  36. public async Task<T> SingleAsync()
  37. {
  38. if (QueryBuilder.OrderByValue.IsNullOrEmpty())
  39. {
  40. QueryBuilder.OrderByValue = QueryBuilder.DefaultOrderByTemplate;
  41. }
  42. var oldSkip = QueryBuilder.Skip;
  43. var oldTake = QueryBuilder.Take;
  44. var oldOrderBy = QueryBuilder.OrderByValue;
  45. QueryBuilder.Skip = null;
  46. QueryBuilder.Take = null;
  47. QueryBuilder.OrderByValue = null;
  48. var result = await this.ToListAsync();
  49. QueryBuilder.Skip = oldSkip;
  50. QueryBuilder.Take = oldTake;
  51. QueryBuilder.OrderByValue = oldOrderBy;
  52. if (result == null || result.Count == 0)
  53. {
  54. return default(T);
  55. }
  56. else if (result.Count == 2)
  57. {
  58. Check.Exception(true, ErrorMessage.GetThrowMessage(".Single() result must not exceed one . You can use.First()", "使用single查询结果集不能大于1,适合主键查询,如果大于1你可以使用Queryable.First"));
  59. return default(T);
  60. }
  61. else
  62. {
  63. return result.SingleOrDefault();
  64. }
  65. }
  66. public async Task<T> SingleAsync(Expression<Func<T, bool>> expression)
  67. {
  68. _Where(expression);
  69. var result = await SingleAsync();
  70. this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last());
  71. return result;
  72. }
  73. public Task<T> FirstAsync(CancellationToken token)
  74. {
  75. this.Context.Ado.CancellationToken = token;
  76. return FirstAsync();
  77. }
  78. public async Task<T> FirstAsync()
  79. {
  80. if (QueryBuilder.OrderByValue.IsNullOrEmpty())
  81. {
  82. QueryBuilder.OrderByValue = QueryBuilder.DefaultOrderByTemplate;
  83. }
  84. if (QueryBuilder.Skip.HasValue)
  85. {
  86. QueryBuilder.Take = 1;
  87. var list = await this.ToListAsync();
  88. return list.FirstOrDefault();
  89. }
  90. else
  91. {
  92. QueryBuilder.Skip = 0;
  93. QueryBuilder.Take = 1;
  94. var result = await this.ToListAsync();
  95. if (result.HasValue())
  96. return result.FirstOrDefault();
  97. else
  98. return default(T);
  99. }
  100. }
  101. public Task<T> FirstAsync(Expression<Func<T, bool>> expression, CancellationToken token)
  102. {
  103. this.Context.Ado.CancellationToken = token;
  104. return FirstAsync(expression);
  105. }
  106. public async Task<T> FirstAsync(Expression<Func<T, bool>> expression)
  107. {
  108. _Where(expression);
  109. var result = await FirstAsync();
  110. this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last());
  111. return result;
  112. }
  113. public async Task<bool> AnyAsync(Expression<Func<T, bool>> expression)
  114. {
  115. _Where(expression);
  116. var result = await AnyAsync();
  117. this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last());
  118. return result;
  119. }
  120. public Task<bool> AnyAsync(Expression<Func<T, bool>> expression, CancellationToken token)
  121. {
  122. this.Context.Ado.CancellationToken = token;
  123. return AnyAsync(expression);
  124. }
  125. public async Task<bool> AnyAsync()
  126. {
  127. return await this.CountAsync() > 0;
  128. }
  129. public Task<int> CountAsync(CancellationToken token)
  130. {
  131. this.Context.Ado.CancellationToken = token;
  132. return CountAsync();
  133. }
  134. public async Task<int> CountAsync()
  135. {
  136. if (this.QueryBuilder.Skip == null &&
  137. this.QueryBuilder.Take == null &&
  138. this.QueryBuilder.OrderByValue == null &&
  139. this.QueryBuilder.PartitionByValue == null &&
  140. this.QueryBuilder.SelectValue == null &&
  141. this.QueryBuilder.Includes == null &&
  142. this.QueryBuilder.IsDistinct == false)
  143. {
  144. var list = await this.Clone().Select<int>(" COUNT(1) ").ToListAsync();
  145. return list.FirstOrDefault();
  146. }
  147. MappingTableList expMapping;
  148. int result;
  149. _CountBegin(out expMapping, out result);
  150. if (IsCache)
  151. {
  152. var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService;
  153. result = CacheSchemeMain.GetOrCreate<int>(cacheService, this.QueryBuilder, () => { return GetCount(); }, CacheTime, this.Context, CacheKey);
  154. }
  155. else
  156. {
  157. result = await GetCountAsync();
  158. }
  159. _CountEnd(expMapping);
  160. return result;
  161. }
  162. public async Task<int> CountAsync(Expression<Func<T, bool>> expression)
  163. {
  164. _Where(expression);
  165. var result = await CountAsync();
  166. this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last());
  167. return result;
  168. }
  169. public Task<int> CountAsync(Expression<Func<T, bool>> expression, CancellationToken token)
  170. {
  171. this.Context.Ado.CancellationToken = token;
  172. return CountAsync(expression);
  173. }
  174. public async Task<TResult> MaxAsync<TResult>(string maxField)
  175. {
  176. this.Select(string.Format(QueryBuilder.MaxTemplate, maxField));
  177. var list = await this._ToListAsync<TResult>();
  178. var result = list.SingleOrDefault();
  179. return result;
  180. }
  181. public Task<TResult> MaxAsync<TResult>(string maxField, CancellationToken token)
  182. {
  183. this.Context.Ado.CancellationToken= token;
  184. return MaxAsync<TResult>(maxField);
  185. }
  186. public Task<TResult> MaxAsync<TResult>(Expression<Func<T, TResult>> expression)
  187. {
  188. return _MaxAsync<TResult>(expression);
  189. }
  190. public Task<TResult> MaxAsync<TResult>(Expression<Func<T, TResult>> expression, CancellationToken token)
  191. {
  192. this.Context.Ado.CancellationToken = token;
  193. return MaxAsync(expression);
  194. }
  195. public async Task<TResult> MinAsync<TResult>(string minField)
  196. {
  197. this.Select(string.Format(QueryBuilder.MinTemplate, minField));
  198. var list = await this._ToListAsync<TResult>();
  199. var result = list.SingleOrDefault();
  200. return result;
  201. }
  202. public Task<TResult> MinAsync<TResult>(Expression<Func<T, TResult>> expression)
  203. {
  204. return _MinAsync<TResult>(expression);
  205. }
  206. public async Task<TResult> SumAsync<TResult>(string sumField)
  207. {
  208. this.Select(string.Format(QueryBuilder.SumTemplate, sumField));
  209. var list = await this._ToListAsync<TResult>();
  210. var result = list.SingleOrDefault();
  211. return result;
  212. }
  213. public Task<TResult> SumAsync<TResult>(Expression<Func<T, TResult>> expression)
  214. {
  215. return _SumAsync<TResult>(expression);
  216. }
  217. public async Task<TResult> AvgAsync<TResult>(string avgField)
  218. {
  219. this.Select(string.Format(QueryBuilder.AvgTemplate, avgField));
  220. var list = await this._ToListAsync<TResult>();
  221. var result = list.SingleOrDefault();
  222. return result;
  223. }
  224. public Task<TResult> AvgAsync<TResult>(Expression<Func<T, TResult>> expression)
  225. {
  226. return _AvgAsync<TResult>(expression);
  227. }
  228. public async virtual Task<List<TResult>> ToListAsync<TResult>(Expression<Func<T, TResult>> expression)
  229. {
  230. if (this.QueryBuilder.Includes != null && this.QueryBuilder.Includes.Count > 0)
  231. {
  232. return await NavSelectHelper.GetListAsync(expression, this);
  233. }
  234. else
  235. {
  236. var list = await this.Select(expression).ToListAsync();
  237. return list;
  238. }
  239. }
  240. public Task<List<T>> ToListAsync()
  241. {
  242. InitMapping();
  243. return _ToListAsync<T>();
  244. }
  245. public Task<List<T>> ToListAsync(CancellationToken token)
  246. {
  247. this.Context.Ado.CancellationToken = token;
  248. return ToListAsync();
  249. }
  250. public Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, CancellationToken token)
  251. {
  252. this.Context.Ado.CancellationToken = token;
  253. return ToPageListAsync(pageNumber, pageSize);
  254. }
  255. public Task<List<T>> ToPageListAsync(int pageIndex, int pageSize)
  256. {
  257. pageIndex = _PageList(pageIndex, pageSize);
  258. return ToListAsync();
  259. }
  260. public async virtual Task<List<TResult>> ToPageListAsync<TResult>(int pageIndex, int pageSize, RefAsync<int> totalNumber, Expression<Func<T, TResult>> expression)
  261. {
  262. if (this.QueryBuilder.Includes != null && this.QueryBuilder.Includes.Count > 0)
  263. {
  264. if (pageIndex == 0)
  265. pageIndex = 1;
  266. var list = await this.Clone().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(expression);
  267. var countQueryable = this.Clone();
  268. countQueryable.QueryBuilder.Includes = null;
  269. totalNumber.Value = await countQueryable.CountAsync();
  270. return list;
  271. }
  272. else
  273. {
  274. var list = await this.Select(expression).ToPageListAsync(pageIndex, pageSize, totalNumber);
  275. return list;
  276. }
  277. }
  278. public Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, RefAsync<int> totalNumber, CancellationToken token)
  279. {
  280. this.Context.Ado.CancellationToken= token;
  281. return ToPageListAsync(pageNumber, pageSize, totalNumber);
  282. }
  283. public async Task<List<T>> ToPageListAsync(int pageIndex, int pageSize, RefAsync<int> totalNumber)
  284. {
  285. var oldMapping = this.Context.MappingTables;
  286. var countQueryable = this.Clone();
  287. if (countQueryable.QueryBuilder.Offset == "true")
  288. {
  289. countQueryable.QueryBuilder.Offset = null;
  290. }
  291. totalNumber.Value = await countQueryable.CountAsync();
  292. this.Context.MappingTables = oldMapping;
  293. return await this.Clone().ToPageListAsync(pageIndex, pageSize);
  294. }
  295. public async Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, RefAsync<int> totalNumber, RefAsync<int> totalPage)
  296. {
  297. var result = await ToPageListAsync(pageNumber, pageSize, totalNumber);
  298. totalPage.Value = (totalNumber.Value + pageSize - 1) / pageSize;
  299. return result;
  300. }
  301. public Task<List<T>> ToPageListAsync(int pageNumber, int pageSize, RefAsync<int> totalNumber, RefAsync<int> totalPage, CancellationToken token)
  302. {
  303. this.Context.Ado.CancellationToken = token;
  304. return ToPageListAsync(pageNumber,pageSize,totalNumber,totalPage);
  305. }
  306. public async Task<string> ToJsonAsync()
  307. {
  308. if (IsCache)
  309. {
  310. var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService;
  311. var result = CacheSchemeMain.GetOrCreate<string>(cacheService, this.QueryBuilder, () =>
  312. {
  313. return this.Context.Utilities.SerializeObject(this.ToList(), typeof(T));
  314. }, CacheTime, this.Context, CacheKey);
  315. return result;
  316. }
  317. else
  318. {
  319. return this.Context.Utilities.SerializeObject(await this.ToListAsync(), typeof(T));
  320. }
  321. }
  322. public async Task<string> ToJsonPageAsync(int pageIndex, int pageSize)
  323. {
  324. return this.Context.Utilities.SerializeObject(await this.ToPageListAsync(pageIndex, pageSize), typeof(T));
  325. }
  326. public async Task<string> ToJsonPageAsync(int pageIndex, int pageSize, RefAsync<int> totalNumber)
  327. {
  328. var oldMapping = this.Context.MappingTables;
  329. totalNumber.Value = await this.Clone().CountAsync();
  330. this.Context.MappingTables = oldMapping;
  331. return await this.Clone().ToJsonPageAsync(pageIndex, pageSize);
  332. }
  333. public async virtual Task<DataTable> ToDataTableByEntityAsync()
  334. {
  335. var list =await this.ToListAsync();
  336. return this.Context.Utilities.ListToDataTable(list);
  337. }
  338. public async Task<DataTable> ToDataTableAsync()
  339. {
  340. QueryBuilder.ResultType = typeof(SugarCacheDataTable);
  341. InitMapping();
  342. var sqlObj = this._ToSql();
  343. RestoreMapping();
  344. DataTable result = null;
  345. if (IsCache)
  346. {
  347. var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService;
  348. result = CacheSchemeMain.GetOrCreate<DataTable>(cacheService, this.QueryBuilder, () => { return this.Db.GetDataTable(sqlObj.Key, sqlObj.Value.ToArray()); }, CacheTime, this.Context, CacheKey);
  349. }
  350. else
  351. {
  352. result = await this.Db.GetDataTableAsync(sqlObj.Key, sqlObj.Value.ToArray());
  353. }
  354. return result;
  355. }
  356. public Task<DataTable> ToDataTablePageAsync(int pageIndex, int pageSize)
  357. {
  358. pageIndex = _PageList(pageIndex, pageSize);
  359. return ToDataTableAsync();
  360. }
  361. public async Task<DataTable> ToDataTablePageAsync(int pageIndex, int pageSize, RefAsync<int> totalNumber)
  362. {
  363. var oldMapping = this.Context.MappingTables;
  364. totalNumber.Value = await this.Clone().CountAsync();
  365. this.Context.MappingTables = oldMapping;
  366. return await this.Clone().ToDataTablePageAsync(pageIndex, pageSize);
  367. }
  368. public async Task<DataTable> ToDataTableByEntityPageAsync(int pageNumber, int pageSize, RefAsync<int> totalNumber)
  369. {
  370. var list =await this.ToPageListAsync(pageNumber, pageSize, totalNumber);
  371. return this.Context.Utilities.ListToDataTable(list);
  372. }
  373. public async Task<List<T>> ToOffsetPageAsync(int pageIndex, int pageSize, RefAsync<int> totalNumber)
  374. {
  375. if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer)
  376. {
  377. this.QueryBuilder.Offset = "true";
  378. return await this.ToPageListAsync(pageIndex, pageSize, totalNumber);
  379. }
  380. else
  381. {
  382. totalNumber.Value = await this.Clone().CountAsync();
  383. _ToOffsetPage(pageIndex, pageSize);
  384. return await this.Clone().ToListAsync();
  385. }
  386. }
  387. public virtual async Task ForEachAsync(Action<T> action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null)
  388. {
  389. Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0, ErrorMessage.GetThrowMessage("no support Skip take, use PageForEach", "不支持Skip Take,请使用 Queryale.PageForEach"));
  390. RefAsync<int> totalNumber = 0;
  391. RefAsync<int> totalPage = 1;
  392. for (int i = 1; i <= totalPage; i++)
  393. {
  394. if (cancellationTokenSource?.IsCancellationRequested == true) return;
  395. var queryable = this.Clone();
  396. var page =
  397. totalPage == 1 ?
  398. await queryable.ToPageListAsync(i, singleMaxReads, totalNumber, totalPage) :
  399. await queryable.ToPageListAsync(i, singleMaxReads);
  400. foreach (var item in page)
  401. {
  402. if (cancellationTokenSource?.IsCancellationRequested == true) return;
  403. action.Invoke(item);
  404. }
  405. }
  406. }
  407. public virtual async Task ForEachByPageAsync(Action<T> action, int pageIndex, int pageSize, RefAsync<int> totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null)
  408. {
  409. int count = this.Clone().Count();
  410. if (count > 0)
  411. {
  412. if (pageSize > singleMaxReads && count - ((pageIndex - 1) * pageSize) > singleMaxReads)
  413. {
  414. Int32 Skip = (pageIndex - 1) * pageSize;
  415. Int32 NowCount = count - Skip;
  416. Int32 number = 0;
  417. if (NowCount > pageSize) NowCount = pageSize;
  418. while (NowCount > 0)
  419. {
  420. if (cancellationTokenSource?.IsCancellationRequested == true) return;
  421. if (number + singleMaxReads > pageSize) singleMaxReads = NowCount;
  422. foreach (var item in await this.Clone().Skip(Skip).Take(singleMaxReads).ToListAsync())
  423. {
  424. if (cancellationTokenSource?.IsCancellationRequested == true) return;
  425. action.Invoke(item);
  426. }
  427. NowCount -= singleMaxReads;
  428. Skip += singleMaxReads;
  429. number += singleMaxReads;
  430. }
  431. }
  432. else
  433. {
  434. if (cancellationTokenSource?.IsCancellationRequested == true) return;
  435. foreach (var item in this.Clone().ToPageList(pageIndex, pageSize))
  436. {
  437. if (cancellationTokenSource?.IsCancellationRequested == true) return;
  438. action.Invoke(item);
  439. }
  440. }
  441. }
  442. totalNumber.Value = count;
  443. }
  444. public async Task<List<T>> SetContextAsync<ParameterT>(Expression<Func<T, object>> thisFiled1, Expression<Func<object>> mappingFiled1,
  445. Expression<Func<T, object>> thisFiled2, Expression<Func<object>> mappingFiled2,
  446. ParameterT parameter)
  447. {
  448. if (parameter == null)
  449. {
  450. return new List<T>();
  451. }
  452. var rightEntity = this.Context.EntityMaintenance.GetEntityInfo<ParameterT>();
  453. var leftEntity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  454. List<T> result = new List<T>();
  455. var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext<ParameterT>;
  456. var list = queryableContext.list;
  457. var key = thisFiled1.ToString() + mappingFiled1.ToString() +
  458. thisFiled2.ToString() + mappingFiled2.ToString() +
  459. typeof(ParameterT).FullName + typeof(T).FullName;
  460. MappingFieldsHelper<ParameterT> fieldsHelper = new MappingFieldsHelper<ParameterT>();
  461. var mappings = new List<MappingFieldsExpression>() {
  462. new MappingFieldsExpression(){
  463. LeftColumnExpression=thisFiled1,
  464. LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled1)),
  465. RightColumnExpression=mappingFiled1,
  466. RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled1))
  467. },
  468. new MappingFieldsExpression(){
  469. LeftColumnExpression=thisFiled2,
  470. LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled2)),
  471. RightColumnExpression=mappingFiled2,
  472. RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled2))
  473. }
  474. };
  475. var conditionals = fieldsHelper.GetMppingSql(list.Cast<object>().ToList(), mappings);
  476. if (queryableContext.TempChildLists == null)
  477. queryableContext.TempChildLists = new Dictionary<string, object>();
  478. if (list != null && queryableContext.TempChildLists.ContainsKey(key))
  479. {
  480. result = (List<T>)queryableContext.TempChildLists[key];
  481. }
  482. else
  483. {
  484. result = await this.Clone().Where(conditionals, true).ToListAsync();
  485. queryableContext.TempChildLists[key] = result;
  486. }
  487. List<object> listObj = result.Select(it => (object)it).ToList();
  488. object obj = (object)parameter;
  489. var newResult = fieldsHelper.GetSetList(obj, listObj, mappings).Select(it => (T)it).ToList();
  490. return newResult;
  491. }
  492. public async Task<List<T>> SetContextAsync<ParameterT>(Expression<Func<T, object>> thisFiled, Expression<Func<object>> mappingFiled, ParameterT parameter)
  493. {
  494. List<T> result = new List<T>();
  495. var entity = this.Context.EntityMaintenance.GetEntityInfo<ParameterT>();
  496. var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext<ParameterT>;
  497. var list = queryableContext.list;
  498. var pkName = "";
  499. if ((mappingFiled as LambdaExpression).Body is UnaryExpression)
  500. {
  501. pkName = (((mappingFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name;
  502. }
  503. else
  504. {
  505. pkName = ((mappingFiled as LambdaExpression).Body as MemberExpression).Member.Name;
  506. }
  507. var key = thisFiled.ToString() + mappingFiled.ToString() + typeof(ParameterT).FullName + typeof(T).FullName;
  508. var ids = list.Select(it => it.GetType().GetProperty(pkName).GetValue(it)).ToArray();
  509. if (queryableContext.TempChildLists == null)
  510. queryableContext.TempChildLists = new Dictionary<string, object>();
  511. if (list != null && queryableContext.TempChildLists.ContainsKey(key))
  512. {
  513. result = (List<T>)queryableContext.TempChildLists[key];
  514. }
  515. else
  516. {
  517. if (queryableContext.TempChildLists == null)
  518. queryableContext.TempChildLists = new Dictionary<string, object>();
  519. await this.Context.Utilities.PageEachAsync(ids, 200, async pageIds =>
  520. {
  521. result.AddRange(await this.Clone().In(thisFiled, pageIds).ToListAsync());
  522. });
  523. queryableContext.TempChildLists[key] = result;
  524. }
  525. var name = "";
  526. if ((thisFiled as LambdaExpression).Body is UnaryExpression)
  527. {
  528. name = (((thisFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name;
  529. }
  530. else
  531. {
  532. name = ((thisFiled as LambdaExpression).Body as MemberExpression).Member.Name;
  533. }
  534. var pkValue = parameter.GetType().GetProperty(pkName).GetValue(parameter);
  535. result = result.Where(it => it.GetType().GetProperty(name).GetValue(it).ObjToString() == pkValue.ObjToString()).ToList();
  536. return result;
  537. }
  538. public async Task<Dictionary<string, object>> ToDictionaryAsync(Expression<Func<T, object>> key, Expression<Func<T, object>> value)
  539. {
  540. if (this.QueryBuilder.IsSingle() == false && (this.QueryBuilder.AsTables == null || this.QueryBuilder.AsTables.Count == 0))
  541. {
  542. return await this.MergeTable().ToDictionaryAsync(key, value);
  543. }
  544. this.QueryBuilder.ResultType = typeof(SugarCacheDictionary);
  545. var keyName = QueryBuilder.GetExpressionValue(key, ResolveExpressType.FieldSingle).GetResultString();
  546. var valueName = QueryBuilder.GetExpressionValue(value, ResolveExpressType.FieldSingle).GetResultString();
  547. var list = await this.Select<KeyValuePair<string, object>>(keyName + "," + valueName).ToListAsync();
  548. var isJson = this.Context.EntityMaintenance.GetEntityInfo<T>().Columns.Where(it => it.IsJson && it.PropertyName == ExpressionTool.GetMemberName(value)).Any();
  549. if (isJson)
  550. {
  551. var result = this.Select<T>(keyName + "," + valueName).ToList().ToDictionary(ExpressionTool.GetMemberName(key), ExpressionTool.GetMemberName(value));
  552. return result;
  553. }
  554. else
  555. {
  556. var result = list.ToDictionary(it => it.Key.ObjToString(), it => it.Value);
  557. return result;
  558. }
  559. }
  560. public async Task<List<T>> ToTreeAsync(string childPropertyName, string parentIdPropertyName, object rootValue, string primaryKeyPropertyName)
  561. {
  562. var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  563. var pk = primaryKeyPropertyName;
  564. var list =await this.ToListAsync();
  565. Expression<Func<T, IEnumerable<object>>> childListExpression = (Expression<Func<T, IEnumerable<object>>>)ExpressionBuilderHelper.CreateExpressionSelectField(typeof(T), childPropertyName, typeof(IEnumerable<object>));
  566. Expression<Func<T, object>> parentIdExpression = (Expression<Func<T, object>>)ExpressionBuilderHelper.CreateExpressionSelectFieldObject(typeof(T), parentIdPropertyName);
  567. return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue) ?? new List<T>();
  568. }
  569. public async Task<List<T>> ToTreeAsync(Expression<Func<T, IEnumerable<object>>> childListExpression, Expression<Func<T, object>> parentIdExpression, object rootValue, object[] childIds)
  570. {
  571. var list = await this.ToListAsync();
  572. return TreeAndFilterIds(childListExpression, parentIdExpression, rootValue, childIds, ref list) ?? new List<T>();
  573. }
  574. public async Task<List<T>> ToTreeAsync(Expression<Func<T, IEnumerable<object>>> childListExpression, Expression<Func<T, object>> parentIdExpression, object rootValue, object[] childIds, Expression<Func<T, object>> primaryKeyExpression)
  575. {
  576. var list = await this.ToListAsync();
  577. return TreeAndFilterIds(childListExpression, parentIdExpression,primaryKeyExpression, rootValue, childIds, ref list) ?? new List<T>();
  578. }
  579. public async Task<List<T>> ToTreeAsync(Expression<Func<T, IEnumerable<object>>> childListExpression, Expression<Func<T, object>> parentIdExpression, object rootValue)
  580. {
  581. var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  582. var pk = GetTreeKey(entity); ;
  583. var list = await this.ToListAsync();
  584. return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue) ?? new List<T>();
  585. }
  586. public async Task<List<T>> ToTreeAsync(Expression<Func<T, IEnumerable<object>>> childListExpression, Expression<Func<T, object>> parentIdExpression, object rootValue, Expression<Func<T, object>> primaryKeyExpression)
  587. {
  588. var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  589. var pk = ExpressionTool.GetMemberName(primaryKeyExpression); ;
  590. var list = await this.ToListAsync();
  591. return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue) ?? new List<T>();
  592. }
  593. public async Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue)
  594. {
  595. List<T> result = new List<T>() { };
  596. var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  597. var isTreeKey = entity.Columns.Any(it => it.IsTreeKey);
  598. if (isTreeKey)
  599. {
  600. return await _ToParentListByTreeKeyAsync(parentIdExpression, primaryKeyValue);
  601. }
  602. Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Count() == 0, "No Primary key");
  603. var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name;
  604. var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName);
  605. var parentPropertyName = ParentInfo.DbColumnName;
  606. var tableName = this.QueryBuilder.GetTableNameString;
  607. if (this.QueryBuilder.IsSingle() == false)
  608. {
  609. if (this.QueryBuilder.JoinQueryInfos.Count > 0)
  610. {
  611. tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
  612. }
  613. if (this.QueryBuilder.EasyJoinInfos.Count > 0)
  614. {
  615. tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
  616. }
  617. }
  618. var current = await this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(primaryKeyValue);
  619. if (current != null)
  620. {
  621. result.Add(current);
  622. object parentId = ParentInfo.PropertyInfo.GetValue(current, null);
  623. int i = 0;
  624. while (parentId != null && await this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).In(parentId).AnyAsync())
  625. {
  626. Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0"));
  627. var parent = await this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(parentId);
  628. result.Add(parent);
  629. parentId = ParentInfo.PropertyInfo.GetValue(parent, null);
  630. ++i;
  631. }
  632. }
  633. return result;
  634. }
  635. public async Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression)
  636. {
  637. List<T> result = new List<T>() { };
  638. var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  639. var isTreeKey = entity.Columns.Any(it => it.IsTreeKey);
  640. if (isTreeKey)
  641. {
  642. return await _ToParentListByTreeKeyAsync(parentIdExpression, primaryKeyValue,parentWhereExpression);
  643. }
  644. Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Count() == 0, "No Primary key");
  645. var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name;
  646. var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName);
  647. var parentPropertyName = ParentInfo.DbColumnName;
  648. var tableName = this.QueryBuilder.GetTableNameString;
  649. if (this.QueryBuilder.IsSingle() == false)
  650. {
  651. if (this.QueryBuilder.JoinQueryInfos.Count > 0)
  652. {
  653. tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
  654. }
  655. if (this.QueryBuilder.EasyJoinInfos.Count > 0)
  656. {
  657. tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
  658. }
  659. }
  660. var current = await this.Context.Queryable<T>().AS(tableName).WhereIF(parentWhereExpression!=default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(primaryKeyValue);
  661. if (current != null)
  662. {
  663. result.Add(current);
  664. object parentId = ParentInfo.PropertyInfo.GetValue(current, null);
  665. int i = 0;
  666. while (parentId != null && await this.Context.Queryable<T>().AS(tableName).WhereIF(parentWhereExpression!=default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).In(parentId).AnyAsync())
  667. {
  668. Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0"));
  669. var parent = await this.Context.Queryable<T>().AS(tableName).WhereIF(parentWhereExpression!=default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(parentId);
  670. result.Add(parent);
  671. parentId = ParentInfo.PropertyInfo.GetValue(parent, null);
  672. ++i;
  673. }
  674. }
  675. return result;
  676. }
  677. public async Task<List<T>> ToChildListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, bool isContainOneself = true)
  678. {
  679. var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  680. var pk = GetTreeKey(entity);
  681. var list = await this.ToListAsync();
  682. return GetChildList(parentIdExpression, pk, list, primaryKeyValue, isContainOneself);
  683. }
  684. public async Task<List<T>> ToChildListAsync(Expression<Func<T, object>> parentIdExpression, object[] primaryKeyValues, bool isContainOneself = true)
  685. {
  686. var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
  687. var pk = GetTreeKey(entity);
  688. var list =await this.ToListAsync();
  689. List<T> result = new List<T>();
  690. foreach (var item in primaryKeyValues)
  691. {
  692. result.AddRange(GetChildList(parentIdExpression, pk, list, item, isContainOneself));
  693. }
  694. return result;
  695. }
  696. public Task<int> IntoTableAsync<TableEntityType>(CancellationToken cancellationToken = default)
  697. {
  698. return IntoTableAsync(typeof(TableEntityType), cancellationToken);
  699. }
  700. public Task<int> IntoTableAsync<TableEntityType>(string TableName, CancellationToken cancellationToken = default)
  701. {
  702. return IntoTableAsync(typeof(TableEntityType), TableName, cancellationToken );
  703. }
  704. public Task<int> IntoTableAsync(Type TableEntityType, CancellationToken cancellationToken = default)
  705. {
  706. var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(TableEntityType);
  707. var name = this.SqlBuilder.GetTranslationTableName(entityInfo.DbTableName);
  708. return IntoTableAsync(TableEntityType, name, cancellationToken);
  709. }
  710. public async Task<int> IntoTableAsync(Type TableEntityType, string TableName, CancellationToken cancellationToken = default)
  711. {
  712. this.Context.Ado.CancellationToken= cancellationToken;
  713. KeyValuePair<string, List<SugarParameter>> sqlInfo;
  714. string sql;
  715. OutIntoTableSql(TableName, out sqlInfo, out sql,TableEntityType);
  716. return await this.Context.Ado.ExecuteCommandAsync(sql, sqlInfo.Value);
  717. }
  718. }
  719. }