예제 #1
0
        /// <summary>
        ///     Bulk Insert 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 Insert Options</param>
        /// <returns></returns>
        public static async Task <int> BulkInsertAsync <DB, T>(this DB dbContext, IEnumerable <T> entities, Expression <Func <T, object> > identificator, Action <BulkInsertOptions <T> > configAction = null)
            where DB : DbContext
            where T : class
        {
            var enumerable = entities.ToList();

            if (!enumerable.Any())
            {
                return(0);
            }

            var options = new BulkInsertOptions <T>();

            configAction?.Invoke(options);

            if (options.FireTriggers)
            {
                TriggersBulk <T, DB> .RaiseInserting(enumerable, dbContext);
            }

            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 bulkInsert = 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()
                             .BulkInsert();

            if (options.IdentityColumn != null)
            {
                bulkInsert = bulkInsert.SetIdentityColumn(options.IdentityColumn, ColumnDirectionType.Input);
            }

            var num = await bulkInsert.CommitAsync(dbContext.Database.Connection as SqlConnection);

            if (options.FireTriggers)
            {
                TriggersBulk <T, DB> .RaiseInserted(enumerable, dbContext, identificator);
            }

            return(num);
        }