1
1

DbContextExt.cs 8.8 KB

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