DbContextExt.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. using Microsoft.EntityFrameworkCore;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Reflection;
  7. namespace Masuit.Tools.Core
  8. {
  9. public static class DbContextExt
  10. {
  11. /// <summary>
  12. /// 获取变化的实体信息
  13. /// </summary>
  14. /// <typeparam name="T"></typeparam>
  15. /// <param name="db"></param>
  16. /// <returns></returns>
  17. public static IEnumerable<ChangeEntry> GetChanges<T>(this DbContext db)
  18. {
  19. return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified && e.Entity is T).Select(e =>
  20. {
  21. var originalObject = e.OriginalValues.ToObject();
  22. var currentObject = e.CurrentValues.ToObject();
  23. return new ChangeEntry
  24. {
  25. EntityState = e.State,
  26. Entity = e.Entity,
  27. EntityType = e.OriginalValues.EntityType.ClrType,
  28. ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo()
  29. {
  30. PropertyInfo = t1.Property.PropertyInfo,
  31. OriginalValue = t1.Value,
  32. CurrentValue = t2.Value,
  33. IsPrimaryKey = t1.Property.IsPrimaryKey(),
  34. IsForeignKey = t1.Property.IsForeignKey()
  35. }).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList()
  36. };
  37. });
  38. }
  39. /// <summary>
  40. /// 获取变化的实体信息
  41. /// </summary>
  42. /// <param name="db"></param>
  43. /// <returns></returns>
  44. public static IEnumerable<ChangeEntry> GetChanges(this DbContext db)
  45. {
  46. return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified).Select(e =>
  47. {
  48. var originalObject = e.OriginalValues.ToObject();
  49. var currentObject = e.CurrentValues.ToObject();
  50. return new ChangeEntry()
  51. {
  52. EntityState = e.State,
  53. Entity = e.Entity,
  54. EntityType = e.OriginalValues.EntityType.ClrType,
  55. ChangeProperties = e.OriginalValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(originalObject))).Zip(e.CurrentValues.Properties.Select(p => (Property: p, Value: p.PropertyInfo.GetValue(currentObject))), (t1, t2) => new ChangePropertyInfo()
  56. {
  57. PropertyInfo = t1.Property.PropertyInfo,
  58. OriginalValue = t1.Value,
  59. CurrentValue = t2.Value,
  60. IsPrimaryKey = t1.Property.IsPrimaryKey(),
  61. IsForeignKey = t1.Property.IsForeignKey(),
  62. }).Where(t => Comparer.Default.Compare(t.OriginalValue, t.CurrentValue) != 0).ToList()
  63. };
  64. });
  65. }
  66. /// <summary>
  67. /// 获取添加的实体信息
  68. /// </summary>
  69. /// <typeparam name="T"></typeparam>
  70. /// <param name="db"></param>
  71. /// <returns></returns>
  72. public static IEnumerable<ChangeEntry> GetAdded<T>(this DbContext db)
  73. {
  74. return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added && e.Entity is T).Select(e =>
  75. {
  76. var currentObject = e.CurrentValues.ToObject();
  77. return new ChangeEntry
  78. {
  79. EntityState = e.State,
  80. Entity = e.Entity,
  81. EntityType = e.CurrentValues.EntityType.ClrType,
  82. ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo()
  83. {
  84. PropertyInfo = p.PropertyInfo,
  85. CurrentValue = p.PropertyInfo.GetValue(currentObject),
  86. IsPrimaryKey = p.IsPrimaryKey(),
  87. IsForeignKey = p.IsForeignKey(),
  88. }).ToList()
  89. };
  90. });
  91. }
  92. /// <summary>
  93. /// 获取添加的实体信息
  94. /// </summary>
  95. /// <param name="db"></param>
  96. /// <returns></returns>
  97. public static IEnumerable<ChangeEntry> GetAdded(this DbContext db)
  98. {
  99. return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Added).Select(e =>
  100. {
  101. var currentObject = e.CurrentValues.ToObject();
  102. return new ChangeEntry
  103. {
  104. EntityState = e.State,
  105. Entity = e.Entity,
  106. EntityType = e.CurrentValues.EntityType.ClrType,
  107. ChangeProperties = e.CurrentValues.Properties.Select(p => new ChangePropertyInfo()
  108. {
  109. PropertyInfo = p.PropertyInfo,
  110. CurrentValue = p.PropertyInfo.GetValue(currentObject),
  111. IsPrimaryKey = p.IsPrimaryKey(),
  112. IsForeignKey = p.IsForeignKey(),
  113. }).ToList()
  114. };
  115. });
  116. }
  117. /// <summary>
  118. /// 获取移除的实体信息
  119. /// </summary>
  120. /// <typeparam name="T"></typeparam>
  121. /// <param name="db"></param>
  122. /// <returns></returns>
  123. public static IEnumerable<ChangeEntry> GetRemoved<T>(this DbContext db)
  124. {
  125. return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted && e.Entity is T).Select(e =>
  126. {
  127. var originalObject = e.OriginalValues.ToObject();
  128. return new ChangeEntry
  129. {
  130. EntityState = e.State,
  131. Entity = e.Entity,
  132. EntityType = e.OriginalValues.EntityType.ClrType,
  133. ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo()
  134. {
  135. PropertyInfo = p.PropertyInfo,
  136. OriginalValue = p.PropertyInfo.GetValue(originalObject),
  137. IsPrimaryKey = p.IsPrimaryKey(),
  138. IsForeignKey = p.IsForeignKey(),
  139. }).ToList()
  140. };
  141. });
  142. }
  143. /// <summary>
  144. /// 获取移除的实体信息
  145. /// </summary>
  146. /// <param name="db"></param>
  147. /// <returns></returns>
  148. public static IEnumerable<ChangeEntry> GetRemoved(this DbContext db)
  149. {
  150. return db.ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted).Select(e =>
  151. {
  152. var originalObject = e.OriginalValues.ToObject();
  153. return new ChangeEntry
  154. {
  155. EntityState = e.State,
  156. Entity = e.Entity,
  157. EntityType = e.OriginalValues.EntityType.ClrType,
  158. ChangeProperties = e.OriginalValues.Properties.Select(p => new ChangePropertyInfo()
  159. {
  160. PropertyInfo = p.PropertyInfo,
  161. OriginalValue = p.PropertyInfo.GetValue(originalObject),
  162. IsPrimaryKey = p.IsPrimaryKey(),
  163. IsForeignKey = p.IsForeignKey(),
  164. }).ToList()
  165. };
  166. });
  167. }
  168. /// <summary>
  169. /// 获取所有的变更信息
  170. /// </summary>
  171. /// <typeparam name="T"></typeparam>
  172. /// <param name="db"></param>
  173. /// <returns></returns>
  174. public static IEnumerable<ChangeEntry> GetAllChanges<T>(this DbContext db)
  175. {
  176. return GetChanges<T>(db).Union(GetAdded<T>(db)).Union(GetRemoved<T>(db));
  177. }
  178. /// <summary>
  179. /// 获取所有的变更信息
  180. /// </summary>
  181. /// <param name="db"></param>
  182. /// <returns></returns>
  183. public static IEnumerable<ChangeEntry> GetAllChanges(this DbContext db)
  184. {
  185. return GetChanges(db).Union(GetAdded(db)).Union(GetRemoved(db));
  186. }
  187. }
  188. public class ChangePropertyInfo
  189. {
  190. /// <summary>
  191. /// 属性
  192. /// </summary>
  193. public PropertyInfo PropertyInfo { get; set; }
  194. /// <summary>
  195. /// 原始值
  196. /// </summary>
  197. public object OriginalValue { get; set; }
  198. /// <summary>
  199. /// 新值
  200. /// </summary>
  201. public object CurrentValue { get; set; }
  202. /// <summary>
  203. /// 是否是主键
  204. /// </summary>
  205. public bool IsPrimaryKey { get; set; }
  206. /// <summary>
  207. /// 是否是外键
  208. /// </summary>
  209. public bool IsForeignKey { get; set; }
  210. }
  211. public class ChangeEntry
  212. {
  213. /// <summary>
  214. /// 所属实体
  215. /// </summary>
  216. public object Entity { get; set; }
  217. /// <summary>
  218. /// 实体类型
  219. /// </summary>
  220. public Type EntityType { get; set; }
  221. /// <summary>
  222. /// 变更类型
  223. /// </summary>
  224. public EntityState EntityState { get; set; }
  225. /// <summary>
  226. /// 字段变更信息
  227. /// </summary>
  228. public List<ChangePropertyInfo> ChangeProperties { get; set; }
  229. }
  230. }