using Microsoft.EntityFrameworkCore; using System.Data; namespace EasyDevCore.Database { /// /// /// public static class DbContextExtensions { /// /// Changes the database. /// /// The database context. /// Name of the database. public static void ChangeDatabase(this DbContext dbContext, string databaseName) { dbContext.Database.OpenConnection(); dbContext.Database.GetDbConnection().ChangeDatabase(databaseName); } /// /// Determines whether [is SQL server]. /// /// The database context. /// /// true if [is SQL server] [the specified database context]; otherwise, false. /// public static bool IsSQLServer(this DbContext dbContext) { return dbContext.Database.ProviderName.EndsWith("SQLServer", StringComparison.InvariantCultureIgnoreCase); } /// /// Determines whether [is my SQL]. /// /// The database context. /// /// true if [is my SQL] [the specified database context]; otherwise, false. /// public static bool IsMySQL(this DbContext dbContext) { return dbContext.Database.ProviderName.EndsWith("MySqlClient", StringComparison.InvariantCultureIgnoreCase); } /// /// Determines whether this instance is Posgres SQL. /// /// The database context. /// /// true if the specified database context is NPGSQL; otherwise, false. /// /// IsNpgsql public static bool IsNpgsql(this DbContext dbContext) { return false; } /// /// Determines whether this instance is Oracle. /// /// The database context. /// /// true if the specified database context is oracle; otherwise, false. /// /// IsOracle public static bool IsOracle(this DbContext dbContext) { return false; } /// /// Saves the change entity. /// /// The context. /// The type. /// if set to true [accept all changes on success]. /// internal static int SaveChangeEntity(this DbContext context, Type type, bool acceptAllChangesOnSuccess = true) { var original = context.ChangeTracker.Entries() .Where(x => !type.IsAssignableFrom(x.Entity.GetType()) && x.State != EntityState.Unchanged) .GroupBy(x => x.State) .ToList(); int rows = 0; try { foreach (var entry in context.ChangeTracker.Entries().Where(x => !type.IsAssignableFrom(x.Entity.GetType()))) { entry.State = EntityState.Unchanged; } rows = context.SaveChanges(acceptAllChangesOnSuccess); } finally { foreach (var state in original) { foreach (var entry in state) { entry.State = state.Key; } } } return rows; } /// /// Saves the change entity asynchronous. /// /// The context. /// The type. /// if set to true [accept all changes on success]. /// The cancellation token. /// internal static async Task SaveChangeEntityAsync(this DbContext context, Type type, bool acceptAllChangesOnSuccess = true, CancellationToken cancellationToken = default) { var original = context.ChangeTracker.Entries() .Where(x => !type.IsAssignableFrom(x.Entity.GetType()) && x.State != EntityState.Unchanged) .GroupBy(x => x.State) .ToList(); int rows = 0; try { foreach (var entry in context.ChangeTracker.Entries().Where(x => !type.IsAssignableFrom(x.Entity.GetType()))) { entry.State = EntityState.Unchanged; } rows = await context.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken).ConfigureAwait(false); } finally { foreach (var state in original) { foreach (var entry in state) { entry.State = state.Key; } } } return rows; } /// /// Saves the changes. /// /// The type of the entity. /// The database context. /// if set to true [accept all changes on success]. /// The entities. /// public static int SaveChanges(this DbContext dbContext, bool acceptAllChangesOnSuccess, params TEntity[] entities) where TEntity : IQueryable { int rows = 0; foreach (var item in entities) { rows += dbContext.SaveChangeEntity(item.GetType(), acceptAllChangesOnSuccess); } return rows; } /// /// Saves the changes. /// /// The type of the entity. /// The database context. /// The entities. /// public static int SaveChanges(this EasyDbContext dbContext, params TEntity[] entities) where TEntity : IQueryable { return dbContext.SaveChanges(true, entities); } /// /// Saves the changes asynchronous. /// /// The type of the entity. /// The database context. /// if set to true [accept all changes on success]. /// The cancellation token. /// The entities. /// public static async Task SaveChangesAsync(this DbContext dbContext, bool acceptAllChangesOnSuccess, CancellationToken cancellationToken, params TEntity[] entities) where TEntity : IQueryable { int rows = 0; foreach (var item in entities) { rows += await dbContext.SaveChangeEntityAsync(item.GetType(), acceptAllChangesOnSuccess, cancellationToken).ConfigureAwait(false); } return rows; } /// /// Saves the changes asynchronous. /// /// The type of the entity. /// The database context. /// if set to true [accept all changes on success]. /// The entities. /// public static async Task SaveChangesAsync(this DbContext dbContext, bool acceptAllChangesOnSuccess, params TEntity[] entities) where TEntity : IQueryable { return await dbContext.SaveChangesAsync(acceptAllChangesOnSuccess, default, entities).ConfigureAwait(false); } /// /// Saves the changes asynchronous. /// /// The type of the entity. /// The database context. /// The entities. /// public static async Task SaveChangesAsync(this DbContext dbContext, params TEntity[] entities) where TEntity : IQueryable { return await dbContext.SaveChangesAsync(true, default, entities).ConfigureAwait(false); } } }