/// <summary> /// Bulk Delete Entities in DB /// </summary> /// <typeparam name="DB">DB Context Type</typeparam> /// <typeparam name="T">Entity Type</typeparam> /// <param name="dbContext">DB Context</param> /// <param name="entities">List of Entities</param> /// <param name="identificator"> /// Expression which generate unique value for each entity. It can be one column or combination /// of columns /// </param> /// <param name="configAction">Configure Bulk Delete Options</param> /// <returns></returns> public static async Task <int> BulkDeleteAsync <DB, T>(this DB dbContext, IEnumerable <T> entities, Expression <Func <T, object> > identificator, Action <BulkDeleteOptions <T> > configAction = null) where DB : DbContext where T : class { var enumerable = entities.ToList(); if (!enumerable.Any()) { return(0); } var options = new BulkDeleteOptions <T>(); configAction?.Invoke(options); if (options.FireTriggers) { TriggersBulk <T, DB> .RaiseDeleting(enumerable, dbContext, identificator); } var bulkDelete = new BulkOperations().Setup <T>() .ForCollection(enumerable) .WithTable(dbContext.GetTableName <T>()) .WithBulkCopySettings(new BulkCopySettings() { BatchSize = options.BatchSize, BulkCopyTimeout = options.Timeout, SqlBulkCopyOptions = options.SqlBulkCopyOptions }) .AddColumn(identificator) .BulkDelete(); var num = await bulkDelete .MatchTargetOn(identificator) .CommitAsync(dbContext.Database.Connection as SqlConnection); if (options.FireTriggers) { TriggersBulk <T, DB> .RaiseDeleted(enumerable, dbContext); } return(num); }
/// <summary> /// Bulk Update Entities in DB /// </summary> /// <typeparam name="DB">DB Context Type</typeparam> /// <typeparam name="T">Entity Type</typeparam> /// <param name="dbContext">DB Context</param> /// <param name="entities">List of Entities</param> /// <param name="identificator"> /// Expression which generate unique value for each entity. It can be one column or combination /// of columns /// </param> /// <param name="configAction">Configure Bulk Update Options</param> /// <returns></returns> public static async Task <int> BulkUpdateAsync <DB, T>(this DB dbContext, IEnumerable <T> entities, Expression <Func <T, object> > identificator, Action <BulkUpdateOptions <T> > configAction = null) where DB : DbContext where T : class { var enumerable = entities.ToList(); if (!enumerable.Any()) { return(0); } var options = new BulkUpdateOptions <T>(); configAction?.Invoke(options); if (options.FireTriggers) { TriggersBulk <T, DB> .RaiseUpdating(enumerable, dbContext, identificator); } var config = new MapperConfiguration(conf => { conf.CreateMap <T, T>().MaxDepth(1).ForAllMembers(c => { if ((c.DestinationMember as PropertyInfo)?.PropertyType.CustomAttributes.Any(x => x.AttributeType == typeof(NotMappedAttribute)) ?? false) { c.Ignore(); } if ((c.DestinationMember as PropertyInfo)?.PropertyType.CustomAttributes.Any(x => x.AttributeType == typeof(ComplexTypeAttribute)) ?? false) { return; } if ((c.DestinationMember as PropertyInfo)?.PropertyType.IsSimple() ?? false) { return; } c.Ignore(); }); }); var mapper = config.CreateMapper(); var distEnts = enumerable.Distinct(new GenericCompare <T>(identificator)).ToList(); var ent = mapper.Map <List <T> >(distEnts); var bulkUpdate = new BulkOperations().Setup <T>() .ForCollection(ent) .WithTable(string.IsNullOrEmpty(options.TableName) ? dbContext.GetTableName <T>() : options.TableName) .WithBulkCopySettings(new BulkCopySettings() { BatchSize = options.BatchSize, BulkCopyTimeout = options.Timeout, SqlBulkCopyOptions = options.SqlBulkCopyOptions }) .AddAllColumns() .DetectColumnWithCustomColumnName() .RemoveNotMappedColumns() .BulkUpdate(); var num = await bulkUpdate .MatchTargetOn(identificator) .CommitAsync(dbContext.Database.Connection as SqlConnection); if (options.FireTriggers) { TriggersBulk <T, DB> .RaiseUpdated(enumerable, dbContext, identificator); } return(num); }