AzureTableDBRepository.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. using TEAMModelOS.SDK.Module.AzureTable.Configuration;
  2. using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
  3. using TEAMModelOS.SDK.Extension.DataResult.PageToken;
  4. using Microsoft.WindowsAzure.Storage.Table;
  5. using System;
  6. using System.Collections.Concurrent;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using TEAMModelOS.SDK.Helper.Security.AESCrypt;
  12. using TEAMModelOS.SDK.Context.Exception;
  13. using System.Reflection;
  14. using TEAMModelOS.SDK.Context.Attributes.Azure;
  15. using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
  16. using TEAMModelOS.SDK.Context.Configuration;
  17. using Microsoft.Extensions.Configuration;
  18. namespace TEAMModelOS.SDK.Module.AzureTable.Implements
  19. {
  20. public class AzureTableDBRepository : IAzureTableDBRepository
  21. {
  22. private readonly string china = "417A7572654368696E612020202020202020202020202020202020202020202097EB27FCC1F03349787DCD35F4DE22BBDFEDC90F24738B1D7FB9167A2C191BE671B512E17D48B73A002FC98867345CD59D3250AF59FD5FDFFC67976108F9E3BC9E9F75EDE605B058C1821D16BD9EB753B8E7D39FF48163430C1B5F3B6150195B880C3FCB87D35BF3540432734B768EC28C77B4CF0D556E794DE57979C1E01C429E66F7B2794D9940CF287F2B22A22E5F266B949D5E523E709FF37229E45D1A8FC8C4341E0A8346BB976CCB3D91802FFE5A4A28577898B4E942B5BA3A4A7B796FA673782D405060E7F2CBA4F67DF59F47";
  23. private readonly string global = "417A757265476C6F62616C2020202020202020202020202020202020202020206956019D195ED330AFA660D369B9464FC5E90AB3A106FDDD7978A2772DB186CDAE21C6CBFDE2B6739F089E853B3171A27841026E61C51666347F63FDF63E4377448D493B05CF6CDB3791946B9145825DD7756392EB8EA36DBF42E5C1C0021CEC2CDB5F4EA57EBCFA98B17D7236FA2CDCA6E7FCBE1DDC45BEAF691A2462A8BC3C429CBC4BCCA3192E554D23758AA8EA5937F988C927534C70A4769ED33878BEC10E2550F121E4AEB5A2DA213F2902D602A758C7D93D5DED368544F8A86D2A0CAA7813D1D950EC81D544EE41A8EDC84173";
  24. private readonly CloudTableClient tableClient;
  25. private CloudTable Table { get; set; }
  26. //public AzureTableDBRepository(AzureTableOptions options)
  27. //{
  28. // if (!string.IsNullOrEmpty(options.ConnectionString))
  29. // {
  30. // tableClient = TableClientSingleton.getInstance(options.ConnectionString).GetTableClient();
  31. // }
  32. // else if (AzureTableConfig.AZURE_CHINA.Equals(options.AzureTableDialect))
  33. // {
  34. // AESCrypt crypt = new AESCrypt();
  35. // tableClient = TableClientSingleton.getInstance(crypt.Decrypt(china, options.AzureTableDialect)).GetTableClient();
  36. // }
  37. // else if (AzureTableConfig.AZURE_GLOBAL.Equals(options.AzureTableDialect))
  38. // {
  39. // AESCrypt crypt = new AESCrypt();
  40. // tableClient = TableClientSingleton.getInstance(crypt.Decrypt(global, options.AzureTableDialect)).GetTableClient();
  41. // }
  42. // else { throw new BizException("请设置正确的AzureTable数据库配置信息!"); }
  43. //}
  44. public AzureTableDBRepository()
  45. {
  46. AzureTableOptions options= BaseConfigModel.Configuration.GetSection("Azure:Table").Get<AzureTableOptions>();
  47. if (!string.IsNullOrEmpty(options.ConnectionString))
  48. {
  49. tableClient = TableClientSingleton.getInstance(options.ConnectionString).GetTableClient();
  50. }
  51. else if (AzureTableConfig.AZURE_CHINA.Equals(options.AzureTableDialect))
  52. {
  53. AESCrypt crypt = new AESCrypt();
  54. tableClient = TableClientSingleton.getInstance(crypt.Decrypt(china, options.AzureTableDialect)).GetTableClient();
  55. }
  56. else if (AzureTableConfig.AZURE_GLOBAL.Equals(options.AzureTableDialect))
  57. {
  58. AESCrypt crypt = new AESCrypt();
  59. tableClient = TableClientSingleton.getInstance(crypt.Decrypt(global, options.AzureTableDialect)).GetTableClient();
  60. }
  61. else { throw new BizException("请设置正确的AzureTable数据库配置信息!"); }
  62. }
  63. private async Task<string> InitializeTable<T>()
  64. {
  65. string TableName = GetTableSpace<T>();
  66. if (Table == null || !Table.Name.Equals(TableName))
  67. {
  68. Table = tableClient.GetTableReference(TableName);
  69. await Table.CreateIfNotExistsAsync();
  70. }
  71. return TableName;
  72. }
  73. private string GetTableSpace<T>()
  74. {
  75. Type type = typeof(T);
  76. string Name = type.Name;
  77. object[] attributes = type.GetCustomAttributes(true);
  78. foreach (object attribute in attributes) //2.通过映射,找到成员属性上关联的特性类实例,
  79. {
  80. if (attribute is TableSpaceAttribute tableSpace)
  81. {
  82. Name = tableSpace.Name + Name;
  83. }
  84. }
  85. return Name;
  86. }
  87. public async Task<List<T>> FindAll<T>() where T : TableEntity, new()
  88. {
  89. string TableName = await InitializeTable<T>();
  90. var exQuery = new TableQuery<T>();
  91. return await QueryList<T>(exQuery, TableName);
  92. }
  93. private async Task<List<T>> QueryList<T>(TableQuery<T> exQuery, string TableName) where T : TableEntity, new()
  94. {
  95. TableContinuationToken continuationToken = null;
  96. List<T> entitys = new List<T>();
  97. do
  98. {
  99. var result = await tableClient.GetTableReference(TableName).ExecuteQuerySegmentedAsync(exQuery, continuationToken);
  100. if (result.Results.Count > 0)
  101. {
  102. entitys.AddRange(result.ToList());
  103. }
  104. continuationToken = result.ContinuationToken;
  105. } while (continuationToken != null);
  106. return entitys;
  107. }
  108. private async Task<T> QueryObject<T>(TableQuery<T> exQuery, string TableName) where T : TableEntity, new()
  109. {
  110. TableContinuationToken continuationToken = null;
  111. T entity = new T();
  112. do
  113. {
  114. var result = await tableClient.GetTableReference(TableName).ExecuteQuerySegmentedAsync(exQuery, continuationToken);
  115. if (result.Results.Count > 0)
  116. {
  117. entity = result.ToList().Single();
  118. }
  119. continuationToken = result.ContinuationToken;
  120. } while (continuationToken != null);
  121. return entity;
  122. }
  123. public async Task<int> Count<T>(TableContinuationToken continuationToken) where T : TableEntity, new()
  124. {
  125. string TableName = await InitializeTable<T>();
  126. var exQuery = new TableQuery<T>();
  127. List<T> entitys = new List<T>();
  128. do
  129. {
  130. var result = await tableClient.GetTableReference(TableName).ExecuteQuerySegmentedAsync(exQuery, continuationToken);
  131. if (result.Results.Count > 0)
  132. {
  133. entitys.AddRange(result.ToList());
  134. }
  135. continuationToken = result.ContinuationToken;
  136. } while (continuationToken != null);
  137. return entitys.Count;
  138. }
  139. public async Task<int> Count<T>() where T : TableEntity, new()
  140. {
  141. string TableName = await InitializeTable<T>();
  142. TableContinuationToken continuationToken = null;
  143. var exQuery = new TableQuery<T>();
  144. List<T> entitys = new List<T>();
  145. do
  146. {
  147. var result = await tableClient.GetTableReference(TableName).ExecuteQuerySegmentedAsync(exQuery, continuationToken);
  148. if (result.Results.Count > 0)
  149. {
  150. entitys.AddRange(result.ToList());
  151. }
  152. continuationToken = result.ContinuationToken;
  153. } while (continuationToken != null);
  154. return entitys.Count;
  155. }
  156. public async Task<T> FindByRowKey<T>(string id) where T : TableEntity, new()
  157. {
  158. string TableName = await InitializeTable<T>();
  159. var exQuery = new TableQuery<T>();
  160. if (!string.IsNullOrEmpty(id))
  161. {
  162. string typeStr = SwitchType<T>(id, "RowKey");
  163. if (string.IsNullOrEmpty(typeStr))
  164. {
  165. return null;
  166. }
  167. exQuery.Where(typeStr);
  168. // exQuery.Where(TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, id));
  169. return await QueryObject<T>(exQuery, TableName);
  170. }
  171. else
  172. {
  173. return null;
  174. }
  175. }
  176. public async Task<List<T>> FindListByDict<T>(Dictionary<string, object> dict) where T : TableEntity, new()
  177. {
  178. string TableName = await InitializeTable<T>();
  179. var exQuery = new TableQuery<T>();
  180. StringBuilder builder = new StringBuilder();
  181. if (null != dict && dict.Count > 0)
  182. {
  183. var keys = dict.Keys;
  184. int index = 1;
  185. foreach (string key in keys)
  186. {
  187. if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
  188. {
  189. string typeStr = SwitchType<T>(dict[key], key);
  190. if(string.IsNullOrEmpty(typeStr))
  191. {
  192. continue;
  193. }
  194. if (index == 1)
  195. {
  196. //builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
  197. builder.Append(typeStr);
  198. }
  199. else
  200. {
  201. //builder.Append(" " + TableOperators.And + " " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
  202. builder.Append(" " + TableOperators.And + " " + typeStr);
  203. }
  204. index++;
  205. }
  206. else {
  207. throw new Exception("The parameter must have value!");
  208. }
  209. }
  210. exQuery.Where(builder.ToString());
  211. return await QueryList<T>(exQuery, TableName);
  212. }
  213. else
  214. {
  215. return null;
  216. }
  217. }
  218. public async Task<List<T>> FindListByKey<T>(string key, object value) where T : TableEntity, new()
  219. {
  220. string TableName = await InitializeTable<T>();
  221. var exQuery = new TableQuery<T>();
  222. if (!string.IsNullOrEmpty(key) && value != null && !string.IsNullOrEmpty(value.ToString()))
  223. {
  224. string typeStr = SwitchType<T>(value, key);
  225. if (string.IsNullOrEmpty(typeStr))
  226. {
  227. return null;
  228. }
  229. exQuery.Where(typeStr);
  230. //exQuery.Where(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, value));
  231. return await QueryList<T>(exQuery, TableName);
  232. }
  233. else
  234. {
  235. return null;
  236. }
  237. }
  238. public async Task<T> FindOneByDict<T>(IDictionary<string, object> dict) where T : TableEntity, new()
  239. {
  240. string TableName = await InitializeTable<T>();
  241. var exQuery = new TableQuery<T>();
  242. StringBuilder builder = new StringBuilder();
  243. if (null != dict && dict.Count > 0)
  244. {
  245. var keys = dict.Keys;
  246. int index = 1;
  247. foreach (string key in keys)
  248. {
  249. if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
  250. {
  251. string typeStr = SwitchType<T>(dict[key], key);
  252. if (string.IsNullOrEmpty(typeStr))
  253. {
  254. continue;
  255. }
  256. if (index == 1)
  257. {
  258. //builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
  259. builder.Append(typeStr);
  260. }
  261. else
  262. {
  263. // builder.Append(" " + TableOperators.And + " " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
  264. builder.Append(" " + TableOperators.And + " " + typeStr);
  265. }
  266. index++;
  267. }
  268. else
  269. {
  270. throw new Exception("The parameter must have value!");
  271. }
  272. }
  273. exQuery.Where(builder.ToString());
  274. return await QueryObject<T>(exQuery, TableName);
  275. }
  276. else
  277. {
  278. return null;
  279. }
  280. }
  281. private static string SwitchType<T>(object obj, string key)
  282. {
  283. Type objType = typeof(T);
  284. PropertyInfo property = objType.GetProperty(key);
  285. //Type s = obj.GetType();
  286. //TypeCode typeCode = Type.GetTypeCode(s);
  287. if (property == null) {
  288. //return null;
  289. throw new Exception(objType.FullName+" PropertyInfo doesn't include this parameter :" +key);
  290. }
  291. TypeCode typeCode = Type.GetTypeCode(property.PropertyType);
  292. switch (typeCode)
  293. {
  294. case TypeCode.String: return TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, obj.ToString());
  295. case TypeCode.Int32: return TableQuery.GenerateFilterConditionForInt(key, QueryComparisons.Equal, int.Parse( obj.ToString()));
  296. case TypeCode.Double: return TableQuery.GenerateFilterConditionForDouble(key, QueryComparisons.Equal, (double)obj);
  297. case TypeCode.Byte: return TableQuery.GenerateFilterConditionForBinary(key, QueryComparisons.Equal, (byte[])obj);
  298. case TypeCode.Boolean: return TableQuery.GenerateFilterConditionForBool(key, QueryComparisons.Equal, (bool)obj);
  299. case TypeCode.DateTime: return TableQuery.GenerateFilterConditionForDate(key, QueryComparisons.Equal, (DateTimeOffset)obj);
  300. case TypeCode.Int64: return TableQuery.GenerateFilterConditionForLong(key, QueryComparisons.Equal, long.Parse(obj.ToString()));
  301. default: return null;
  302. }
  303. }
  304. public async Task<T> FindOneByKey<T>(string key, object value) where T : TableEntity, new()
  305. {
  306. string TableName = await InitializeTable<T>();
  307. var exQuery = new TableQuery<T>();
  308. if (!string.IsNullOrEmpty(key) && value != null && !string.IsNullOrEmpty(value.ToString()))
  309. {
  310. string typeStr = SwitchType<T>(value, key);
  311. if (string.IsNullOrEmpty(typeStr))
  312. {
  313. return null;
  314. }
  315. exQuery.Where(typeStr);
  316. //exQuery.Where(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal,
  317. // value));
  318. return await QueryObject<T>(exQuery, TableName);
  319. }
  320. else
  321. {
  322. return null;
  323. }
  324. }
  325. public async Task<List<T>> GetEntities<T>(IDictionary<string, object> dict) where T : TableEntity, new()
  326. {
  327. string TableName = await InitializeTable<T>();
  328. var exQuery = new TableQuery<T>();
  329. StringBuilder builder = new StringBuilder();
  330. if (null != dict && dict.Count > 0)
  331. {
  332. var keys = dict.Keys;
  333. int index = 1;
  334. foreach (string key in keys)
  335. {
  336. if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
  337. {
  338. string typeStr = SwitchType<T>(dict, key);
  339. if (string.IsNullOrEmpty(typeStr))
  340. {
  341. continue;
  342. }
  343. if (index == 1)
  344. {
  345. //builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
  346. builder.Append(typeStr);
  347. }
  348. else
  349. {
  350. // builder.Append(" " + TableOperators.And + " " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
  351. builder.Append(" " + TableOperators.And + " " + typeStr);
  352. }
  353. index++;
  354. }
  355. else
  356. {
  357. throw new Exception("The parameter must have value!");
  358. }
  359. }
  360. exQuery.Where(builder.ToString());
  361. return await QueryList<T>(exQuery, TableName);
  362. }
  363. else
  364. {
  365. return null;
  366. }
  367. }
  368. public async Task<List<T>> SaveAll<T>(List<T> entitys) where T : TableEntity, new()
  369. {
  370. if (entitys.IsEmpty())
  371. {
  372. return null;
  373. }
  374. string TableName = await InitializeTable<T>();
  375. IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
  376. foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
  377. {
  378. Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
  379. {
  380. { group.Key, group.ToList() }
  381. };
  382. listInfo.Add(dictInfo);
  383. }
  384. foreach (Dictionary<string, List<T>> dict in listInfo)
  385. {
  386. IList<TableResult> result = null;
  387. foreach (string key in dict.Keys)
  388. {
  389. List<T> values = dict[key];
  390. //Parallel.ForEach(Partitioner.Create(0, values.Count, 100),
  391. // async range =>
  392. // {
  393. // TableBatchOperation batchOperation = new TableBatchOperation();
  394. // for (Int32 i = range.Item1; i < range.Item2; i++)
  395. // batchOperation.Insert(values[i]);
  396. // result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
  397. // });
  398. int pageSize = 100;
  399. int pages = (int)Math.Ceiling((double)values.Count / pageSize);
  400. for (int i = 0; i < pages; i++)
  401. {
  402. List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
  403. TableBatchOperation batchOperation = new TableBatchOperation();
  404. for (int j = 0; j < lists.Count; j++)
  405. {
  406. batchOperation.Insert(lists[j]);
  407. }
  408. result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
  409. }
  410. }
  411. }
  412. return entitys;
  413. }
  414. public async Task<List<T>> UpdateAll<T>(List<T> entitys) where T : TableEntity, new()
  415. {
  416. if (entitys.IsEmpty())
  417. {
  418. return null;
  419. }
  420. string TableName = await InitializeTable<T>();
  421. IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
  422. foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
  423. {
  424. Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
  425. {
  426. { group.Key, group.ToList() }
  427. };
  428. listInfo.Add(dictInfo);
  429. }
  430. foreach (Dictionary<string, List<T>> dict in listInfo)
  431. {
  432. IList<TableResult> result = null;
  433. foreach (string key in dict.Keys)
  434. {
  435. List<T> values = dict[key];
  436. //Parallel.ForEach(Partitioner.Create(0, values.Count, 100),
  437. // async range =>
  438. // {
  439. // TableBatchOperation batchOperation = new TableBatchOperation();
  440. // for (Int32 i = range.Item1; i < range.Item2; i++)
  441. // batchOperation.Replace(values[i]);
  442. // result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
  443. // });
  444. int pageSize = 100;
  445. int pages = (int)Math.Ceiling((double)values.Count / pageSize);
  446. for (int i = 0; i < pages; i++)
  447. {
  448. List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
  449. TableBatchOperation batchOperation = new TableBatchOperation();
  450. for (int j = 0; j < lists.Count; j++)
  451. {
  452. batchOperation.Replace(lists[j]);
  453. }
  454. result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
  455. }
  456. }
  457. }
  458. return entitys;
  459. }
  460. public async Task<List<T>> SaveOrUpdateAll<T>(List<T> entitys) where T : TableEntity, new()
  461. {
  462. if (entitys.IsEmpty())
  463. {
  464. return null;
  465. }
  466. string TableName = await InitializeTable<T>();
  467. IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
  468. foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
  469. {
  470. Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
  471. {
  472. { group.Key, group.ToList() }
  473. };
  474. listInfo.Add(dictInfo);
  475. }
  476. foreach (Dictionary<string, List<T>> dict in listInfo)
  477. {
  478. IList<TableResult> result = null;
  479. foreach (string key in dict.Keys)
  480. {
  481. List<T> values = dict[key];
  482. //Parallel.ForEach(Partitioner.Create(0, values.Count, 50),
  483. // async range =>
  484. // {
  485. // TableBatchOperation batchOperation = new TableBatchOperation();
  486. // for (Int32 i = range.Item1; i < range.Item2; i++)
  487. // batchOperation.InsertOrReplace(values[i]);
  488. // result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
  489. // });
  490. int pageSize = 100;
  491. int pages = (int)Math.Ceiling((double)values.Count/ pageSize);
  492. for (int i= 0; i < pages; i++) {
  493. List<T> lists= values.Skip((i) * pageSize).Take(pageSize).ToList();
  494. TableBatchOperation batchOperation = new TableBatchOperation();
  495. for (int j = 0; j < lists.Count; j++)
  496. {
  497. batchOperation.InsertOrReplace(lists[j]);
  498. }
  499. result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
  500. }
  501. }
  502. }
  503. return entitys;
  504. }
  505. public async Task<List<T>> DeleteAll<T>(List<T> entitys) where T : TableEntity, new()
  506. {
  507. if (entitys.IsEmpty())
  508. {
  509. return null;
  510. }
  511. string TableName = await InitializeTable<T>();
  512. IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
  513. foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
  514. {
  515. Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
  516. {
  517. { group.Key, group.ToList() }
  518. };
  519. listInfo.Add(dictInfo);
  520. }
  521. foreach (Dictionary<string, List<T>> dict in listInfo)
  522. {
  523. IList<TableResult> result = null;
  524. foreach (string key in dict.Keys)
  525. {
  526. List<T> values = dict[key];
  527. //Parallel.ForEach(Partitioner.Create(0, values.Count, 100),
  528. // async range =>
  529. // {
  530. // TableBatchOperation batchOperation = new TableBatchOperation();
  531. // for (Int32 i = range.Item1; i < range.Item2; i++)
  532. // batchOperation.Delete(values[i]);
  533. // result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
  534. // });
  535. int pageSize = 100;
  536. int pages = (int)Math.Ceiling((double)values.Count / pageSize);
  537. for (int i = 0; i < pages; i++)
  538. {
  539. List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
  540. TableBatchOperation batchOperation = new TableBatchOperation();
  541. for (int j = 0; j < lists.Count; j++)
  542. {
  543. batchOperation.Delete(lists[j]);
  544. }
  545. result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
  546. }
  547. }
  548. }
  549. return entitys;
  550. }
  551. public async Task<T> Save<T>(TableEntity entity) where T : TableEntity, new()
  552. {
  553. string TableName = await InitializeTable<T>();
  554. TableOperation operation = TableOperation.Insert(entity);
  555. TableResult result = await tableClient.GetTableReference(TableName).ExecuteAsync(operation);
  556. return (T)result.Result;
  557. }
  558. public async Task<T> SaveOrUpdate<T>(TableEntity entity) where T : TableEntity, new()
  559. {
  560. string TableName = await InitializeTable<T>();
  561. TableOperation operation = TableOperation.InsertOrReplace(entity);
  562. TableResult result = await tableClient.GetTableReference(TableName).ExecuteAsync(operation);
  563. return (T)result.Result;
  564. }
  565. public async Task<T> Update<T>(TableEntity entity) where T : TableEntity, new()
  566. {
  567. string TableName = await InitializeTable<T>();
  568. TableOperation operation = TableOperation.Replace(entity);
  569. TableResult result = await tableClient.GetTableReference(TableName).ExecuteAsync(operation);
  570. return (T)result.Result;
  571. }
  572. public async Task<T> Delete<T>(TableEntity entity) where T : TableEntity, new()
  573. {
  574. string TableName = await InitializeTable<T>();
  575. TableOperation operation = TableOperation.Delete(entity);
  576. TableResult result = await tableClient.GetTableReference(TableName).ExecuteAsync(operation);
  577. return (T)result.Result;
  578. }
  579. //public async Task<List<T>> FindListByDictAndLike<T>(Dictionary<string, object> dict, Dictionary<string, object> likeDict) where T : TableEntity, new()
  580. //{
  581. // throw new NotImplementedException();
  582. //}
  583. //public async Task<List<T>> FindListByDictAndLikeAndNotEQ<T>(Dictionary<string, object> dict, Dictionary<string, object> likeDict, Dictionary<string, object> notEQDict) where T : TableEntity, new()
  584. //{
  585. // throw new NotImplementedException();
  586. //}
  587. //public async Task<List<T>> FindListByDictAndLikeAndStartWith<T>(Dictionary<string, object> dict, Dictionary<string, object> likeDict, Dictionary<string, object> startDict) where T : TableEntity, new()
  588. //{
  589. // throw new NotImplementedException();
  590. //}
  591. public async Task<AzurePagination<T>> FindListByDict<T>(Dictionary<string, object> dict, AzureTableToken azureTableToken) where T : TableEntity, new()
  592. {
  593. string TableName = await InitializeTable<T>();
  594. var exQuery = new TableQuery<T>();
  595. StringBuilder builder = new StringBuilder();
  596. if (null != dict && dict.Count > 0)
  597. {
  598. var keys = dict.Keys;
  599. int index = 1;
  600. foreach (string key in keys)
  601. {
  602. if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
  603. {
  604. string typeStr = SwitchType<T>(dict, key);
  605. if (string.IsNullOrEmpty(typeStr))
  606. {
  607. continue;
  608. }
  609. if (index == 1)
  610. {
  611. // builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
  612. builder.Append(typeStr);
  613. }
  614. else
  615. {
  616. builder.Append(" " + TableOperators.And + " " + typeStr);
  617. //builder.Append(" " + TableOperators.And + " " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
  618. }
  619. index++;
  620. }
  621. else
  622. {
  623. throw new Exception("The parameter must have value!");
  624. }
  625. }
  626. exQuery.Where(builder.ToString());
  627. return await QueryList<T>(azureTableToken, exQuery, TableName);
  628. }
  629. else
  630. {
  631. return null;
  632. }
  633. }
  634. private async Task<AzurePagination<T>> QueryList<T>(AzureTableToken azureTableToken, TableQuery<T> exQuery, string TableName) where T : TableEntity, new()
  635. {
  636. TableContinuationToken tableToken = new HaBookTableContinuationToken(azureTableToken).GetContinuationToken();
  637. List<T> entitys = new List<T>();
  638. var result = await tableClient.GetTableReference(TableName).ExecuteQuerySegmentedAsync(exQuery, tableToken);
  639. if (result.Results.Count > 0)
  640. {
  641. entitys.AddRange(result.ToList());
  642. }
  643. tableToken = result.ContinuationToken;
  644. AzurePagination<T> pagination = new AzurePagination<T>
  645. {
  646. token = new HaBookTableContinuationToken(tableToken).GetAzureTableToken(),
  647. data = entitys
  648. };
  649. return pagination;
  650. }
  651. }
  652. }