DbContextExtensions.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. using Microsoft.EntityFrameworkCore;
  2. using System.Data;
  3. namespace EasyDevCore.Database.EntityFrameworkCore
  4. {
  5. /// <summary>
  6. ///
  7. /// </summary>
  8. public static class DbContextExtensions
  9. {
  10. /// <summary>
  11. /// Changes the database.
  12. /// </summary>
  13. /// <param name="dbContext">The database context.</param>
  14. /// <param name="databaseName">Name of the database.</param>
  15. public static void ChangeDatabase(this DbContext dbContext, string databaseName)
  16. {
  17. dbContext.Database.OpenConnection();
  18. dbContext.Database.GetDbConnection().ChangeDatabase(databaseName);
  19. }
  20. /// <summary>
  21. /// Determines whether [is SQL server].
  22. /// </summary>
  23. /// <param name="dbContext">The database context.</param>
  24. /// <returns>
  25. /// <c>true</c> if [is SQL server] [the specified database context]; otherwise, <c>false</c>.
  26. /// </returns>
  27. public static bool IsSQLServer(this DbContext dbContext)
  28. {
  29. return dbContext.Database.ProviderName.EndsWith("SQLServer", StringComparison.InvariantCultureIgnoreCase);
  30. }
  31. /// <summary>
  32. /// Determines whether [is my SQL].
  33. /// </summary>
  34. /// <param name="dbContext">The database context.</param>
  35. /// <returns>
  36. /// <c>true</c> if [is my SQL] [the specified database context]; otherwise, <c>false</c>.
  37. /// </returns>
  38. public static bool IsMySQL(this DbContext dbContext)
  39. {
  40. return dbContext.Database.ProviderName.EndsWith("MySqlClient", StringComparison.InvariantCultureIgnoreCase);
  41. }
  42. /// <summary>
  43. /// Determines whether this instance is Posgres SQL.
  44. /// </summary>
  45. /// <param name="dbContext">The database context.</param>
  46. /// <returns>
  47. /// <c>true</c> if the specified database context is NPGSQL; otherwise, <c>false</c>.
  48. /// </returns>
  49. /// <exception cref="NotImplementedException">IsNpgsql</exception>
  50. public static bool IsNpgsql(this DbContext dbContext)
  51. {
  52. return false;
  53. }
  54. /// <summary>
  55. /// Determines whether this instance is Oracle.
  56. /// </summary>
  57. /// <param name="dbContext">The database context.</param>
  58. /// <returns>
  59. /// <c>true</c> if the specified database context is oracle; otherwise, <c>false</c>.
  60. /// </returns>
  61. /// <exception cref="NotImplementedException">IsOracle</exception>
  62. public static bool IsOracle(this DbContext dbContext)
  63. {
  64. return false;
  65. }
  66. /// <summary>
  67. /// Saves the change entity.
  68. /// </summary>
  69. /// <param name="context">The context.</param>
  70. /// <param name="type">The type.</param>
  71. /// <param name="acceptAllChangesOnSuccess">if set to <c>true</c> [accept all changes on success].</param>
  72. /// <returns></returns>
  73. internal static int SaveChangeEntity(this DbContext context, Type type, bool acceptAllChangesOnSuccess = true)
  74. {
  75. var original = context.ChangeTracker.Entries()
  76. .Where(x => !type.IsAssignableFrom(x.Entity.GetType()) && x.State != EntityState.Unchanged)
  77. .GroupBy(x => x.State)
  78. .ToList();
  79. int rows = 0;
  80. try
  81. {
  82. foreach (var entry in context.ChangeTracker.Entries().Where(x => !type.IsAssignableFrom(x.Entity.GetType())))
  83. {
  84. entry.State = EntityState.Unchanged;
  85. }
  86. rows = context.SaveChanges(acceptAllChangesOnSuccess);
  87. }
  88. finally
  89. {
  90. foreach (var state in original)
  91. {
  92. foreach (var entry in state)
  93. {
  94. entry.State = state.Key;
  95. }
  96. }
  97. }
  98. return rows;
  99. }
  100. /// <summary>
  101. /// Saves the change entity asynchronous.
  102. /// </summary>
  103. /// <param name="context">The context.</param>
  104. /// <param name="type">The type.</param>
  105. /// <param name="acceptAllChangesOnSuccess">if set to <c>true</c> [accept all changes on success].</param>
  106. /// <param name="cancellationToken">The cancellation token.</param>
  107. /// <returns></returns>
  108. internal static async Task<int> SaveChangeEntityAsync(this DbContext context, Type type, bool acceptAllChangesOnSuccess = true, CancellationToken cancellationToken = default)
  109. {
  110. var original = context.ChangeTracker.Entries()
  111. .Where(x => !type.IsAssignableFrom(x.Entity.GetType()) && x.State != EntityState.Unchanged)
  112. .GroupBy(x => x.State)
  113. .ToList();
  114. int rows = 0;
  115. try
  116. {
  117. foreach (var entry in context.ChangeTracker.Entries().Where(x => !type.IsAssignableFrom(x.Entity.GetType())))
  118. {
  119. entry.State = EntityState.Unchanged;
  120. }
  121. rows = await context.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken).ConfigureAwait(false);
  122. }
  123. finally
  124. {
  125. foreach (var state in original)
  126. {
  127. foreach (var entry in state)
  128. {
  129. entry.State = state.Key;
  130. }
  131. }
  132. }
  133. return rows;
  134. }
  135. /// <summary>
  136. /// Saves the changes.
  137. /// </summary>
  138. /// <typeparam name="TEntity">The type of the entity.</typeparam>
  139. /// <param name="dbContext">The database context.</param>
  140. /// <param name="acceptAllChangesOnSuccess">if set to <c>true</c> [accept all changes on success].</param>
  141. /// <param name="entities">The entities.</param>
  142. /// <returns></returns>
  143. public static int SaveChanges<TEntity>(this DbContext dbContext, bool acceptAllChangesOnSuccess, params TEntity[] entities) where TEntity : IQueryable
  144. {
  145. int rows = 0;
  146. foreach (var item in entities)
  147. {
  148. rows += dbContext.SaveChangeEntity(item.GetType(), acceptAllChangesOnSuccess);
  149. }
  150. return rows;
  151. }
  152. /// <summary>
  153. /// Saves the changes.
  154. /// </summary>
  155. /// <typeparam name="TEntity">The type of the entity.</typeparam>
  156. /// <param name="dbContext">The database context.</param>
  157. /// <param name="entities">The entities.</param>
  158. /// <returns></returns>
  159. public static int SaveChanges<TEntity>(this EasyDbContext dbContext, params TEntity[] entities) where TEntity : IQueryable
  160. {
  161. return dbContext.SaveChanges(true, entities);
  162. }
  163. /// <summary>
  164. /// Saves the changes asynchronous.
  165. /// </summary>
  166. /// <typeparam name="TEntity">The type of the entity.</typeparam>
  167. /// <param name="dbContext">The database context.</param>
  168. /// <param name="acceptAllChangesOnSuccess">if set to <c>true</c> [accept all changes on success].</param>
  169. /// <param name="cancellationToken">The cancellation token.</param>
  170. /// <param name="entities">The entities.</param>
  171. /// <returns></returns>
  172. public static async Task<int> SaveChangesAsync<TEntity>(this DbContext dbContext, bool acceptAllChangesOnSuccess, CancellationToken cancellationToken, params TEntity[] entities) where TEntity : IQueryable
  173. {
  174. int rows = 0;
  175. foreach (var item in entities)
  176. {
  177. rows += await dbContext.SaveChangeEntityAsync(item.GetType(), acceptAllChangesOnSuccess, cancellationToken).ConfigureAwait(false);
  178. }
  179. return rows;
  180. }
  181. /// <summary>
  182. /// Saves the changes asynchronous.
  183. /// </summary>
  184. /// <typeparam name="TEntity">The type of the entity.</typeparam>
  185. /// <param name="dbContext">The database context.</param>
  186. /// <param name="acceptAllChangesOnSuccess">if set to <c>true</c> [accept all changes on success].</param>
  187. /// <param name="entities">The entities.</param>
  188. /// <returns></returns>
  189. public static async Task<int> SaveChangesAsync<TEntity>(this DbContext dbContext, bool acceptAllChangesOnSuccess, params TEntity[] entities) where TEntity : IQueryable
  190. {
  191. return await dbContext.SaveChangesAsync(acceptAllChangesOnSuccess, default, entities).ConfigureAwait(false);
  192. }
  193. /// <summary>
  194. /// Saves the changes asynchronous.
  195. /// </summary>
  196. /// <typeparam name="TEntity">The type of the entity.</typeparam>
  197. /// <param name="dbContext">The database context.</param>
  198. /// <param name="entities">The entities.</param>
  199. /// <returns></returns>
  200. public static async Task<int> SaveChangesAsync<TEntity>(this DbContext dbContext, params TEntity[] entities) where TEntity : IQueryable
  201. {
  202. return await dbContext.SaveChangesAsync(true, default, entities).ConfigureAwait(false);
  203. }
  204. }
  205. }