UnitOfWork.cs 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using EMIS.Entities;
  6. using System.Data.SqlClient;
  7. using System.Data;
  8. using System.Data.Entity;
  9. using System.Data.Entity.Validation;
  10. using System.Diagnostics;
  11. using System.Data.Entity.Core.Objects;
  12. using System.Data.Entity.Core.Metadata.Edm;
  13. using System.Data.Entity.Infrastructure;
  14. using System.Linq.Expressions;
  15. using System.Reflection;
  16. using EMIS.Utility.Log;
  17. using System.Collections;
  18. using Bowin.Common.Linq.DB;
  19. using System.Configuration;
  20. using Bowin.Common.Linq;
  21. using Bowin.Common.Linq.Entity;
  22. namespace EMIS.DataLogic
  23. {
  24. public class UnitOfWork : EMISNewContext, IDisposable
  25. {
  26. public UnitOfWork()
  27. : base("EMISNewContext")
  28. {
  29. }
  30. public TEntity Add<TEntity>(TEntity entity) where TEntity : class
  31. {
  32. return Set<TEntity>().Add(entity);
  33. }
  34. public IEnumerable<TEntity> AddRange<TEntity>(IEnumerable<TEntity> entityList) where TEntity : class
  35. {
  36. return Set<TEntity>().AddRange(entityList);
  37. }
  38. public TEntity Attach<TEntity>(TEntity entity) where TEntity : class
  39. {
  40. return Set<TEntity>().Attach(entity);
  41. }
  42. /// <summary>
  43. /// 事务提交
  44. /// </summary>
  45. public void Commit()
  46. {
  47. var logs = DbLog.GetLog(this.ChangeTracker).Concat(
  48. DbLog.GetRelationshipLog(this)).ToList();
  49. try
  50. {
  51. SaveChanges();
  52. logs.ForEach(x => x.IsSuccess = true);
  53. LogUnitOfWork.WriteLogs(logs);
  54. }
  55. catch (DbEntityValidationException dbEx)
  56. {
  57. logs.ForEach(x => x.IsSuccess = false);
  58. LogUnitOfWork.WriteLogs(logs);
  59. foreach (var validationErrors in dbEx.EntityValidationErrors)
  60. {
  61. foreach (var validationError in validationErrors.ValidationErrors)
  62. {
  63. Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
  64. }
  65. }
  66. throw dbEx;
  67. }
  68. catch (Exception ex)
  69. {
  70. logs.ForEach(x => x.IsSuccess = false);
  71. LogUnitOfWork.WriteLogs(logs);
  72. throw ex;
  73. }
  74. }
  75. /// <summary>
  76. /// 创建只有ID字段的临时表
  77. /// </summary>
  78. /// <param name="TempTableName"></param>
  79. public void CreateIDTempTable(string TempTableName, List<Guid?> Id)
  80. {
  81. SqlConnection conn = GetConnection();
  82. if (conn.State == ConnectionState.Closed)
  83. {
  84. conn.Open();
  85. }
  86. string sql = "";
  87. StringBuilder sb = new StringBuilder();
  88. if (Id.Count == 0)
  89. {
  90. sb.Append(@"CREATE TABLE [" + TempTableName + "] (ID UNIQUEIDENTIFIER NOT NULL)");
  91. }
  92. else
  93. {
  94. sb.Append(@"CREATE TABLE [" + TempTableName + "] (ID UNIQUEIDENTIFIER NOT NULL) INSERT INTO [" + TempTableName + "] VALUES");
  95. foreach (var i in Id)
  96. {
  97. sb.Append("(" + "'" + i + "'" + "),");
  98. }
  99. sb.Remove(sb.Length - 1, 1);
  100. }
  101. sql = sb.ToString();
  102. try
  103. {
  104. var command = new SqlCommand(sql, conn);
  105. command.CommandTimeout = 12000;
  106. command.CommandType = System.Data.CommandType.Text;
  107. command.ExecuteNonQuery();
  108. }
  109. catch (Exception)
  110. {
  111. throw;
  112. }
  113. }
  114. /// <summary>
  115. /// 删除只有ID字段的临时表
  116. /// </summary>
  117. /// <param name="TempTableName"></param>
  118. public void DeleteTempTable(string TempTableName)
  119. {
  120. SqlConnection conn = GetConnection();
  121. if (conn.State == ConnectionState.Closed)
  122. {
  123. conn.Open();
  124. }
  125. string sql = "";
  126. StringBuilder sb = new StringBuilder();
  127. sb.Append(@"DROP TABLE [" + TempTableName + "] ");
  128. sql = sb.ToString();
  129. try
  130. {
  131. var command = new SqlCommand(sql, conn);
  132. command.CommandTimeout = 12000;
  133. command.CommandType = System.Data.CommandType.Text;
  134. command.ExecuteNonQuery();
  135. }
  136. catch (Exception)
  137. {
  138. throw;
  139. }
  140. }
  141. /// <summary>
  142. /// 批量更新
  143. /// </summary>
  144. /// <typeparam name="TEntity"></typeparam>
  145. /// <typeparam name="TField"></typeparam>
  146. /// <typeparam name="TKey"></typeparam>
  147. /// <param name="uow"></param>
  148. /// <param name="data"></param>
  149. /// <param name="fields"></param>
  150. /// <param name="keys"></param>
  151. public void BatchUpdate<TEntity>(IList<TEntity> data) where TEntity : class
  152. {
  153. var logList = DbLog.GetBatchUpdateLog(data, this);
  154. string setField = "";
  155. string keyExpression = "";
  156. string tableName = typeof(TEntity).Name;
  157. var properties = typeof(TEntity).GetProperties();
  158. string tableKey = "";
  159. PropertyInfo keyProperty;
  160. try
  161. {
  162. tableKey = TableKeyDictionary.GetKeyName<TEntity>();
  163. keyProperty = typeof(TEntity).GetProperty(tableKey);
  164. }
  165. catch
  166. {
  167. throw new Exception("批量修改出错,输入的实体没有正确对应的主键,请检查输入。");
  168. }
  169. foreach (var property in properties)
  170. {
  171. if (property.PropertyType.IsPrimitive || property.PropertyType.IsValueType || property.PropertyType.Name.StartsWith("String"))
  172. {
  173. var field = property.Name;
  174. if (setField != "")
  175. {
  176. setField += ",";
  177. }
  178. setField += "[" + field + "]" + "=dest.[" + field + "]";
  179. }
  180. }
  181. if (keyProperty.PropertyType.IsPrimitive || keyProperty.PropertyType.IsValueType || keyProperty.PropertyType.Name.StartsWith("String"))
  182. {
  183. keyExpression = "source.[" + keyProperty.Name + "]" + "=dest.[" + keyProperty.Name + "]";
  184. }
  185. string tmpTableName = "##UpdateTemp" + Guid.NewGuid().ToString().Replace("-", "");
  186. SqlConnection conn = GetConnection();
  187. conn.BulkCopyToTempTable(tmpTableName, data);
  188. string sql = @"update " + tableName + @" set " + setField + @" from " + tableName + @" source inner join " + tmpTableName + @" dest on " + keyExpression;
  189. try
  190. {
  191. var command = new SqlCommand(sql, conn);
  192. command.CommandTimeout = 12000;
  193. command.CommandType = System.Data.CommandType.Text;
  194. command.ExecuteNonQuery();
  195. try
  196. {
  197. command.CommandText = "drop table " + tmpTableName;
  198. command.CommandType = System.Data.CommandType.Text;
  199. command.ExecuteNonQuery();
  200. }
  201. catch { }
  202. logList.ForEach(x => x.IsSuccess = true);
  203. LogUnitOfWork.WriteLogs(logList);
  204. }
  205. catch (Exception)
  206. {
  207. logList.ForEach(x => x.IsSuccess = false);
  208. LogUnitOfWork.WriteLogs(logList);
  209. throw;
  210. }
  211. }
  212. public void BulkInsert<TEntity>(IList<TEntity> data) where TEntity : class
  213. {
  214. var logList = DbLog.GetBulkInsertLog(data);
  215. try
  216. {
  217. var db = GetConnection();
  218. data.ExecuteBulkCopy(db, typeof(TEntity).Name);
  219. logList.ForEach(x => x.IsSuccess = true);
  220. LogUnitOfWork.WriteLogs(logList);
  221. }
  222. catch (Exception ex)
  223. {
  224. logList.ForEach(x => x.IsSuccess = false);
  225. LogUnitOfWork.WriteLogs(logList);
  226. throw ex;
  227. }
  228. }
  229. public void BulkInsert<TEntity1, TEntity2>(IList<Relation2KeyTable> data)
  230. {
  231. var tableName1 = typeof(TEntity1).Name;
  232. var tableName2 = typeof(TEntity2).Name;
  233. var metadata = ((IObjectContextAdapter)this).ObjectContext.MetadataWorkspace;
  234. var associationSet = metadata.GetItemCollection(DataSpace.SSpace)
  235. .GetItems<EntityContainer>().Single()
  236. .AssociationSets.Where(x => x.AssociationSetEnds.Any(w => w.Name == tableName1)
  237. && (x.AssociationSetEnds.Any(w => w.Name == tableName1 + tableName2) || x.AssociationSetEnds.Any(w => w.Name == tableName2 + tableName1))).FirstOrDefault();
  238. if (associationSet == null) { return; }
  239. bool isSourceSet;
  240. var targetSetProperty = typeof(AssociationSet).GetProperty("TargetSet", BindingFlags.Instance | BindingFlags.NonPublic);
  241. var sourceSetProperty = typeof(AssociationSet).GetProperty("SourceSet", BindingFlags.Instance | BindingFlags.NonPublic);
  242. var targetSet = ((System.Data.Entity.Core.Metadata.Edm.EntitySet)(targetSetProperty.GetValue(associationSet, null)));
  243. var sourceSet = ((System.Data.Entity.Core.Metadata.Edm.EntitySet)(sourceSetProperty.GetValue(associationSet, null)));
  244. var tableName = targetSet.Table;
  245. if (tableName == null)
  246. {
  247. tableName = sourceSet.Table;
  248. isSourceSet = false;
  249. if (tableName == null || tableName == tableName1)
  250. {
  251. return;
  252. }
  253. }
  254. else
  255. {
  256. isSourceSet = true;
  257. }
  258. var key1 = TableKeyDictionary.GetKeyName<TEntity1>();
  259. var key2 = TableKeyDictionary.GetKeyName<TEntity2>();
  260. var keyProperty = typeof(TEntity1).GetProperty(key1);
  261. var targetKeyPropery = typeof(TEntity2).GetProperty(key2);
  262. var resultTable = new DataTable(tableName);
  263. var db = GetConnection();
  264. var columnList = db.GetTableColumns(tableName);
  265. if (columnList.First().ToLower() == key1.ToLower())
  266. {
  267. resultTable.Columns.Add(key1, typeof(Guid));
  268. resultTable.Columns.Add(key2, typeof(Guid));
  269. }
  270. else
  271. {
  272. resultTable.Columns.Add(key2, typeof(Guid));
  273. resultTable.Columns.Add(key1, typeof(Guid));
  274. }
  275. foreach (var dataItem in data)
  276. {
  277. var row = resultTable.NewRow();
  278. row[0] = dataItem.Key1;
  279. row[1] = dataItem.Key2;
  280. resultTable.Rows.Add(row);
  281. }
  282. var logList = DbLog.GetBulkInsertLog(resultTable, tableName);
  283. try
  284. {
  285. BulkCopyExtensions.ExecuteBulkCopy(db, resultTable);
  286. logList.ForEach(x => x.IsSuccess = true);
  287. LogUnitOfWork.WriteLogs(logList);
  288. }
  289. catch (Exception ex)
  290. {
  291. logList.ForEach(x => x.IsSuccess = false);
  292. LogUnitOfWork.WriteLogs(logList);
  293. throw ex;
  294. }
  295. }
  296. public void BulkInsert<TEntity, TProperty>(IList<TEntity> data, Expression<Func<TEntity, TProperty>> relationShip)
  297. {
  298. if (!typeof(TProperty).FullName.Contains("HashSet"))
  299. {
  300. return;
  301. }
  302. var tableName1 = typeof(TEntity).Name;
  303. var targetProperty = (PropertyInfo)((MemberExpression)relationShip.Body).Member;
  304. var tableName2 = targetProperty.Name;
  305. var metadata = ((IObjectContextAdapter)this).ObjectContext.MetadataWorkspace;
  306. var associationSet = metadata.GetItemCollection(DataSpace.SSpace)
  307. .GetItems<EntityContainer>().Single()
  308. .AssociationSets.Where(x => x.AssociationSetEnds.Any(w => w.Name == tableName1)
  309. && (x.AssociationSetEnds.Any(w => w.Name == tableName1 + tableName2) || x.AssociationSetEnds.Any(w => w.Name == tableName2 + tableName1))).FirstOrDefault();
  310. if (associationSet == null) { return; }
  311. bool isSourceSet;
  312. var targetSetProperty = typeof(AssociationSet).GetProperty("TargetSet", BindingFlags.Instance | BindingFlags.NonPublic);
  313. var sourceSetProperty = typeof(AssociationSet).GetProperty("SourceSet", BindingFlags.Instance | BindingFlags.NonPublic);
  314. var targetSet = ((System.Data.Entity.Core.Metadata.Edm.EntitySet)(targetSetProperty.GetValue(associationSet, null)));
  315. var sourceSet = ((System.Data.Entity.Core.Metadata.Edm.EntitySet)(sourceSetProperty.GetValue(associationSet, null)));
  316. var tableName = targetSet.Table;
  317. if (tableName == null)
  318. {
  319. tableName = sourceSet.Table;
  320. isSourceSet = false;
  321. if (tableName == null || tableName == tableName1)
  322. {
  323. return;
  324. }
  325. }
  326. else
  327. {
  328. isSourceSet = true;
  329. }
  330. var targetElementType = (typeof(TProperty)).GetGenericArguments()[0];
  331. var key1 = TableKeyDictionary.GetKeyName<TEntity>();
  332. var key2 = TableKeyDictionary.GetKeyName(targetElementType.Assembly.CreateInstance(targetElementType.FullName));
  333. var keyProperty = typeof(TEntity).GetProperty(key1);
  334. var targetKeyPropery = targetElementType.GetProperty(key2);
  335. var resultTable = new DataTable(tableName);
  336. var db = GetConnection();
  337. var columnList = db.GetTableColumns(tableName);
  338. if (columnList.First().ToLower() == key1.ToLower())
  339. {
  340. resultTable.Columns.Add(key1, typeof(Guid));
  341. resultTable.Columns.Add(key2, typeof(Guid));
  342. }
  343. else
  344. {
  345. resultTable.Columns.Add(key2, typeof(Guid));
  346. resultTable.Columns.Add(key1, typeof(Guid));
  347. }
  348. foreach (var dataItem in data)
  349. {
  350. IEnumerable targetHashset = (IEnumerable)targetProperty.GetValue(dataItem, null);
  351. foreach (var target in targetHashset)
  352. {
  353. var row = resultTable.NewRow();
  354. if (columnList.First().ToLower() == key1.ToLower())
  355. {
  356. row[0] = (Guid)keyProperty.GetValue(dataItem, null);
  357. row[1] = (Guid)targetKeyPropery.GetValue(target, null);
  358. }
  359. else
  360. {
  361. row[0] = (Guid)targetKeyPropery.GetValue(target, null);
  362. row[1] = (Guid)keyProperty.GetValue(dataItem, null);
  363. }
  364. resultTable.Rows.Add(row);
  365. }
  366. }
  367. var logList = DbLog.GetBulkInsertLog(resultTable, tableName);
  368. try
  369. {
  370. BulkCopyExtensions.ExecuteBulkCopy(db, resultTable);
  371. logList.ForEach(x => x.IsSuccess = true);
  372. LogUnitOfWork.WriteLogs(logList);
  373. }
  374. catch (Exception ex)
  375. {
  376. logList.ForEach(x => x.IsSuccess = false);
  377. LogUnitOfWork.WriteLogs(logList);
  378. throw ex;
  379. }
  380. }
  381. private SqlConnection GetConnection()
  382. {
  383. var connectionKey = typeof(EMISNewContext).Name;
  384. //if (!SqlConnectionManager.IsGlobalConnectionStarted)
  385. //{
  386. // SqlConnectionManager.InitConnections();
  387. //}
  388. return (SqlConnection)((DbContext)this).Database.Connection;
  389. }
  390. public TEntity Remove<TEntity>(TEntity entity) where TEntity : class
  391. {
  392. Set<TEntity>().Attach(entity);
  393. return Set<TEntity>().Remove(entity);
  394. }
  395. public void Remove<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class
  396. {
  397. var entities = this.Set<TEntity>().Where(where).ToList();
  398. Set<TEntity>().RemoveRange(entities);
  399. }
  400. public void RemoveRange<TEntity>(HashSet<TEntity> entities) where TEntity : class
  401. {
  402. Set<TEntity>().RemoveRange(entities);
  403. }
  404. void IDisposable.Dispose()
  405. {
  406. Dispose();
  407. }
  408. public void Update<TEntity>(TEntity entity) where TEntity : class
  409. {
  410. Entry<TEntity>(entity).State = System.Data.Entity.EntityState.Modified;
  411. }
  412. public event Action<object> PostUpdate;
  413. public void Update<TEntity>(Expression<Func<TEntity, TEntity>> setExpression, Expression<Func<TEntity, bool>> whereExpression) where TEntity : class
  414. {
  415. var entities = this.Set<TEntity>().Where(whereExpression).ToList();
  416. entities.ForEach(x =>
  417. {
  418. foreach (var binding in ((MemberInitExpression)setExpression.Body).Bindings)
  419. {
  420. PropertyInfo property = (PropertyInfo)binding.Member;
  421. var expression = ((MemberAssignment)binding).Expression;
  422. if (expression is ConstantExpression)
  423. {
  424. property.SetValue(x, ((ConstantExpression)expression).Value, null);
  425. }
  426. else
  427. {
  428. property.SetValue(x, Expression.Lambda(expression, setExpression.Parameters.ToArray()).Compile()
  429. .DynamicInvoke(x), null);
  430. }
  431. }
  432. });
  433. var logList = DbLog.GetBatchUpdateLog(entities, this);
  434. try
  435. {
  436. EntityFramework.Extensions.BatchExtensions.Update(this.Set<TEntity>().Where(whereExpression), setExpression);
  437. logList.ForEach(x => x.IsSuccess = true);
  438. LogUnitOfWork.WriteLogs(logList);
  439. }
  440. catch (Exception ex)
  441. {
  442. logList.ForEach(x => x.IsSuccess = false);
  443. LogUnitOfWork.WriteLogs(logList);
  444. throw ex;
  445. }
  446. }
  447. public void Delete<TEntity>(Expression<Func<TEntity, bool>> whereExpression) where TEntity : class
  448. {
  449. var entities = this.Set<TEntity>().Where(whereExpression).ToList();
  450. if (entities.Count == 0) return;
  451. var logList = DbLog.GetDeleteLog(entities);
  452. try
  453. {
  454. ((DbContext)this).Delete(whereExpression);
  455. logList.ForEach(x => x.IsSuccess = true);
  456. LogUnitOfWork.WriteLogs(logList);
  457. }
  458. catch (Exception ex)
  459. {
  460. logList.ForEach(x => x.IsSuccess = false);
  461. LogUnitOfWork.WriteLogs(logList);
  462. throw ex;
  463. }
  464. //entities.ForEach(x => this.Remove(x));
  465. //this.Commit();
  466. }
  467. public void Delete<TEntity>(IList<TEntity> entityList) where TEntity : class
  468. {
  469. if (entityList.Count == 0) return;
  470. var tableName = typeof(TEntity).Name;
  471. var tableKey = TableKeyDictionary.GetKeyName<TEntity>();
  472. var logList = DbLog.GetDeleteLog(Bowin.Common.Data.ConvertToDataTable.ToTable(entityList), tableName);
  473. try
  474. {
  475. var db = GetConnection();
  476. string tmpTableName = "##DeleteTemp" + Guid.NewGuid().ToString().Replace("-", "");
  477. db.BulkCopyToTempTable(tmpTableName, entityList);
  478. string sql = @"
  479. delete t
  480. from " + tableName + @" t
  481. inner join " + tmpTableName + @" tmp on
  482. t.[" + tableKey + "]=tmp.[" + tableKey + "]";
  483. var command = new SqlCommand(sql, db);
  484. command.CommandTimeout = 12000;
  485. command.CommandType = CommandType.Text;
  486. command.ExecuteNonQuery();
  487. command.CommandText = "drop table " + tmpTableName;
  488. command.CommandType = System.Data.CommandType.Text;
  489. command.ExecuteNonQuery();
  490. logList.ForEach(x => x.IsSuccess = true);
  491. LogUnitOfWork.WriteLogs(logList);
  492. }
  493. catch (Exception ex)
  494. {
  495. logList.ForEach(x => x.IsSuccess = false);
  496. LogUnitOfWork.WriteLogs(logList);
  497. throw ex;
  498. }
  499. }
  500. public void Delete<TEntity, TProperty>(IList<TEntity> entityList, Expression<Func<TEntity, TProperty>> relationShip)
  501. {
  502. if (entityList.Count == 0) return;
  503. if (!typeof(TProperty).FullName.Contains("HashSet"))
  504. {
  505. return;
  506. }
  507. var tableName1 = typeof(TEntity).Name;
  508. var targetProperty = (PropertyInfo)((MemberExpression)relationShip.Body).Member;
  509. var tableName2 = targetProperty.Name;
  510. var metadata = ((IObjectContextAdapter)this).ObjectContext.MetadataWorkspace;
  511. var associationSet = metadata.GetItemCollection(DataSpace.SSpace)
  512. .GetItems<EntityContainer>().Single()
  513. .AssociationSets.Where(x => x.AssociationSetEnds.Any(w => w.Name == tableName1)
  514. && (x.AssociationSetEnds.Any(w => w.Name == tableName1 + tableName2) || x.AssociationSetEnds.Any(w => w.Name == tableName2 + tableName1))).FirstOrDefault();
  515. if (associationSet == null) { return; }
  516. bool isSourceSet;
  517. var targetSetProperty = typeof(AssociationSet).GetProperty("TargetSet", BindingFlags.Instance | BindingFlags.NonPublic);
  518. var sourceSetProperty = typeof(AssociationSet).GetProperty("SourceSet", BindingFlags.Instance | BindingFlags.NonPublic);
  519. var targetSet = ((System.Data.Entity.Core.Metadata.Edm.EntitySet)(targetSetProperty.GetValue(associationSet, null)));
  520. var sourceSet = ((System.Data.Entity.Core.Metadata.Edm.EntitySet)(sourceSetProperty.GetValue(associationSet, null)));
  521. var tableName = targetSet.Table;
  522. if (tableName == null)
  523. {
  524. tableName = sourceSet.Table;
  525. isSourceSet = false;
  526. if (tableName == null || tableName == tableName1)
  527. {
  528. return;
  529. }
  530. }
  531. else
  532. {
  533. isSourceSet = true;
  534. }
  535. var targetElementType = (typeof(TProperty)).GetGenericArguments()[0];
  536. var key1 = TableKeyDictionary.GetKeyName<TEntity>();
  537. var key2 = TableKeyDictionary.GetKeyName(targetElementType.Assembly.CreateInstance(targetElementType.FullName));
  538. var keyProperty = typeof(TEntity).GetProperty(key1);
  539. var targetKeyPropery = targetElementType.GetProperty(key2);
  540. var resultTable = new DataTable(tableName);
  541. if (isSourceSet)
  542. {
  543. resultTable.Columns.Add(key1, typeof(Guid));
  544. resultTable.Columns.Add(key2, typeof(Guid));
  545. }
  546. else
  547. {
  548. resultTable.Columns.Add(key2, typeof(Guid));
  549. resultTable.Columns.Add(key1, typeof(Guid));
  550. }
  551. List<Guid> keyList = new List<Guid>();
  552. foreach (var entity in entityList)
  553. {
  554. IEnumerable targetHashset = (IEnumerable)targetProperty.GetValue(entity, null);
  555. foreach (var target in targetHashset)
  556. {
  557. var row = resultTable.NewRow();
  558. if (isSourceSet)
  559. {
  560. row[0] = (Guid)keyProperty.GetValue(entity, null);
  561. row[1] = (Guid)targetKeyPropery.GetValue(target, null);
  562. }
  563. else
  564. {
  565. row[0] = (Guid)targetKeyPropery.GetValue(target, null);
  566. row[1] = (Guid)keyProperty.GetValue(entity, null);
  567. }
  568. keyList.Add((Guid)keyProperty.GetValue(entity, null));
  569. resultTable.Rows.Add(row);
  570. }
  571. }
  572. var logList = DbLog.GetDeleteLog(resultTable, tableName);
  573. try
  574. {
  575. var db = GetConnection();
  576. string tmpTableName = "##DeleteTemp" + Guid.NewGuid().ToString().Replace("-", "");
  577. db.BulkCopyToTempTable(tmpTableName, keyList, keyProperty.Name);
  578. string sql = @"
  579. delete t
  580. from " + tableName + @" t
  581. inner join " + tmpTableName + @" tmp on
  582. t.[" + keyProperty.Name + "]=tmp.[" + keyProperty.Name + "]";
  583. var command = new SqlCommand(sql, db);
  584. command.CommandTimeout = 12000;
  585. command.CommandType = CommandType.Text;
  586. command.ExecuteNonQuery();
  587. command.CommandText = "drop table " + tmpTableName;
  588. command.CommandType = System.Data.CommandType.Text;
  589. command.ExecuteNonQuery();
  590. logList.ForEach(x => x.IsSuccess = true);
  591. LogUnitOfWork.WriteLogs(logList);
  592. }
  593. catch (Exception ex)
  594. {
  595. logList.ForEach(x => x.IsSuccess = false);
  596. LogUnitOfWork.WriteLogs(logList);
  597. throw ex;
  598. }
  599. }
  600. public void Delete<TEntity, TProperty>(TEntity entity, Expression<Func<TEntity, TProperty>> relationShip)
  601. {
  602. if (entity == null) return;
  603. if (!typeof(TProperty).FullName.Contains("HashSet"))
  604. {
  605. return;
  606. }
  607. var tableName1 = typeof(TEntity).Name;
  608. var targetProperty = (PropertyInfo)((MemberExpression)relationShip.Body).Member;
  609. var tableName2 = targetProperty.Name;
  610. var metadata = ((IObjectContextAdapter)this).ObjectContext.MetadataWorkspace;
  611. var associationSet = metadata.GetItemCollection(DataSpace.SSpace)
  612. .GetItems<EntityContainer>().Single()
  613. .AssociationSets.Where(x => x.AssociationSetEnds.Any(w => w.Name == tableName1)
  614. && (x.AssociationSetEnds.Any(w => w.Name == tableName1 + tableName2) || x.AssociationSetEnds.Any(w => w.Name == tableName2 + tableName1))).FirstOrDefault();
  615. if (associationSet == null) { return; }
  616. bool isSourceSet;
  617. var targetSetProperty = typeof(AssociationSet).GetProperty("TargetSet", BindingFlags.Instance | BindingFlags.NonPublic);
  618. var sourceSetProperty = typeof(AssociationSet).GetProperty("SourceSet", BindingFlags.Instance | BindingFlags.NonPublic);
  619. var targetSet = ((System.Data.Entity.Core.Metadata.Edm.EntitySet)(targetSetProperty.GetValue(associationSet, null)));
  620. var sourceSet = ((System.Data.Entity.Core.Metadata.Edm.EntitySet)(sourceSetProperty.GetValue(associationSet, null)));
  621. var tableName = targetSet.Table;
  622. if (tableName == null)
  623. {
  624. tableName = sourceSet.Table;
  625. isSourceSet = false;
  626. if (tableName == null || tableName == tableName1)
  627. {
  628. return;
  629. }
  630. }
  631. else
  632. {
  633. isSourceSet = true;
  634. }
  635. var targetElementType = (typeof(TProperty)).GetGenericArguments()[0];
  636. var key1 = TableKeyDictionary.GetKeyName<TEntity>();
  637. var key2 = TableKeyDictionary.GetKeyName(targetElementType.Assembly.CreateInstance(targetElementType.FullName));
  638. var keyProperty = typeof(TEntity).GetProperty(key1);
  639. var targetKeyPropery = targetElementType.GetProperty(key2);
  640. var resultTable = new DataTable(tableName);
  641. if (isSourceSet)
  642. {
  643. resultTable.Columns.Add(key1, typeof(Guid));
  644. resultTable.Columns.Add(key2, typeof(Guid));
  645. }
  646. else
  647. {
  648. resultTable.Columns.Add(key2, typeof(Guid));
  649. resultTable.Columns.Add(key1, typeof(Guid));
  650. }
  651. IEnumerable targetHashset = (IEnumerable)targetProperty.GetValue(entity, null);
  652. foreach (var target in targetHashset)
  653. {
  654. var row = resultTable.NewRow();
  655. if (isSourceSet)
  656. {
  657. row[0] = (Guid)keyProperty.GetValue(entity, null);
  658. row[1] = (Guid)targetKeyPropery.GetValue(target, null);
  659. }
  660. else
  661. {
  662. row[0] = (Guid)targetKeyPropery.GetValue(target, null);
  663. row[1] = (Guid)keyProperty.GetValue(entity, null);
  664. }
  665. resultTable.Rows.Add(row);
  666. }
  667. var logList = DbLog.GetDeleteLog(resultTable, tableName);
  668. try
  669. {
  670. var db = GetConnection();
  671. db.Delete(tableName, key1, (Guid)keyProperty.GetValue(entity, null));
  672. logList.ForEach(x => x.IsSuccess = true);
  673. LogUnitOfWork.WriteLogs(logList);
  674. }
  675. catch (Exception ex)
  676. {
  677. logList.ForEach(x => x.IsSuccess = false);
  678. LogUnitOfWork.WriteLogs(logList);
  679. throw ex;
  680. }
  681. }
  682. int ExecuteSQL(string sql, params object[] parameters)
  683. {
  684. return this.Database.ExecuteSqlCommand(sql, parameters);
  685. }
  686. public void BatchUpdate<TKey>(string tableName, string columnName, object value, IList<TKey> idList)
  687. {
  688. var assembly = typeof(EMISNewContext).Assembly;
  689. var entityType = assembly.GetTypes().Where(x => x.Name.ToLower() == tableName.ToLower()).FirstOrDefault();
  690. var methodInfo = typeof(UnitOfWork).GetMethods()
  691. .Where(x => x.ContainsGenericParameters && x.GetGenericArguments().Length == 2 && x.Name == "BatchUpdate"
  692. && x.GetParameters().Length == 3).FirstOrDefault();
  693. methodInfo = methodInfo
  694. .MakeGenericMethod(entityType, typeof(TKey));
  695. methodInfo.Invoke(this, new object[] { columnName, value, idList });
  696. }
  697. public void BatchUpdate<TEntity, TKey>(string columnName, object value, IList<TKey> idList) where TEntity : class
  698. {
  699. var curUser = EMIS.Utility.FormValidate.CustomPrincipal.Current;
  700. ExpressionFactory<TEntity> factory = new ExpressionFactory<TEntity>(Set<TEntity>());
  701. var para = Expression.Parameter(typeof(TEntity));
  702. var property = typeof(TEntity).GetProperty(columnName);
  703. var modifytime = typeof(TEntity).GetProperty("ModifyTime");
  704. var modifyuser = typeof(TEntity).GetProperty("ModifyUserID");
  705. object timevalue = DateTime.Now;
  706. object uservalue = curUser.UserID;
  707. MemberInitExpression memberExpression;
  708. if (modifytime != null)
  709. {
  710. var newExpression = Expression.New(typeof(TEntity).GetConstructor(new Type[] { }));
  711. var bindValue = GetValueExpression(value, property);
  712. MemberAssignment bindExpression;
  713. if (bindValue == null)
  714. {
  715. bindExpression = Expression.Bind(property, Expression.Constant(null, property.PropertyType));
  716. }
  717. else
  718. {
  719. bindExpression = Expression.Bind(property, GetValueExpression(value, property));
  720. }
  721. var timebindExpression = Expression.Bind(modifytime, GetValueExpression(timevalue, modifytime));
  722. var userbindExpression = Expression.Bind(modifyuser, GetValueExpression(uservalue, modifyuser));
  723. memberExpression = Expression.MemberInit(newExpression, new MemberBinding[] { bindExpression, timebindExpression, userbindExpression });
  724. }
  725. else
  726. {
  727. var newExpression = Expression.New(typeof(TEntity).GetConstructor(new Type[] { }));
  728. var bindExpression = Expression.Bind(property, GetValueExpression(value, property));
  729. memberExpression = Expression.MemberInit(newExpression, new MemberBinding[] { bindExpression });
  730. }
  731. Expression<Func<TEntity, TEntity>> setExpression = Expression.Lambda<Func<TEntity, TEntity>>(memberExpression, para);
  732. Expression<Func<TEntity, bool>> whereExpression = factory.DynamicInExpression(TableKeyDictionary.GetKeyName<TEntity>(), idList);
  733. this.Update(setExpression, whereExpression);
  734. }
  735. public void BatchUpdate<TKey>(string tableName, IDictionary<string, object> valueList, IList<TKey> idList)
  736. {
  737. var assembly = typeof(EMISNewContext).Assembly;
  738. var entityType = assembly.GetTypes().Where(x => x.Name.ToLower() == tableName.ToLower()).FirstOrDefault();
  739. var methodInfo = typeof(UnitOfWork).GetMethods()
  740. .Where(x => x.ContainsGenericParameters && x.GetGenericArguments().Length == 2 && x.Name == "BatchUpdate"
  741. && x.GetParameters().Length == 2).FirstOrDefault();
  742. methodInfo = methodInfo
  743. .MakeGenericMethod(entityType, typeof(TKey));
  744. methodInfo.Invoke(this, new object[] { valueList, idList });
  745. }
  746. public void BatchUpdate<TEntity, TKey>(IDictionary<string, object> valueList, IList<TKey> idList) where TEntity : class
  747. {
  748. var curUser = EMIS.Utility.FormValidate.CustomPrincipal.Current;
  749. ExpressionFactory<TEntity> factory = new ExpressionFactory<TEntity>(Set<TEntity>());
  750. var para = Expression.Parameter(typeof(TEntity));
  751. var newExpression = Expression.New(typeof(TEntity).GetConstructor(new Type[] { }));
  752. var memberBindingList = new List<MemberBinding>();
  753. foreach (var keyValue in valueList)
  754. {
  755. var property = typeof(TEntity).GetProperty(keyValue.Key);
  756. var bindExpression = Expression.Bind(property, GetValueExpression(keyValue.Value, property));
  757. memberBindingList.Add(bindExpression);
  758. }
  759. var modifytime = typeof(TEntity).GetProperty("ModifyTime");
  760. var modifyuser = typeof(TEntity).GetProperty("ModifyUserID");
  761. if (modifytime != null)
  762. {
  763. object timevalue = DateTime.Now;
  764. var timebindExpression = Expression.Bind(modifytime, GetValueExpression(timevalue, modifytime));
  765. memberBindingList.Add(timebindExpression);
  766. }
  767. if (modifyuser != null)
  768. {
  769. object uservalue = curUser.UserID;
  770. var userbindExpression = Expression.Bind(modifyuser, GetValueExpression(uservalue, modifyuser));
  771. memberBindingList.Add(userbindExpression);
  772. }
  773. var memberExpression = Expression.MemberInit(newExpression, memberBindingList.ToArray());
  774. Expression<Func<TEntity, TEntity>> setExpression = Expression.Lambda<Func<TEntity, TEntity>>(memberExpression, para);
  775. Expression<Func<TEntity, bool>> whereExpression = factory.DynamicInExpression(TableKeyDictionary.GetKeyName<TEntity>(), idList);
  776. this.Update(setExpression, whereExpression);
  777. }
  778. private Expression GetValueExpression(object value, PropertyInfo property)
  779. {
  780. if (property.PropertyType == typeof(Guid) || property.PropertyType == typeof(Guid?))
  781. {
  782. return Expression.Constant(Guid.Parse(value.ToString()));
  783. }
  784. else if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?))
  785. {
  786. if (value == null && property.PropertyType == typeof(int?))
  787. {
  788. return null;
  789. }
  790. return Expression.Constant(int.Parse(value.ToString()));
  791. }
  792. else if (property.PropertyType == typeof(short) || property.PropertyType == typeof(short?))
  793. {
  794. return Expression.Constant(short.Parse(value.ToString()));
  795. }
  796. else if (property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?))
  797. {
  798. if (value.Equals("1") || value.Equals("0"))
  799. return Expression.Constant(value.Equals("1"));
  800. return Expression.Constant(bool.Parse(value.ToString()));
  801. }
  802. else if (property.PropertyType == typeof(decimal) || property.PropertyType == typeof(decimal?))
  803. {
  804. return Expression.Constant(decimal.Parse(value.ToString()));
  805. }
  806. else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?))
  807. {
  808. return Expression.Constant(DateTime.Parse(value.ToString()));
  809. }
  810. else
  811. {
  812. return Expression.Convert(Expression.Constant(value), property.PropertyType);
  813. }
  814. }
  815. }
  816. public class Relation2KeyTable
  817. {
  818. public Guid Key1 { get; set; }
  819. public Guid Key2 { get; set; }
  820. }
  821. }