zoukankan      html  css  js  c++  java
  • EntityFramework进阶(四)- 实现批量新增

    本系列原创博客代码已在EntityFramework6.0.0测试通过,转载请标明出处

    我们可以结合Ado.Net的SqlBulkCopy实现SqlServer数据库的批量新增,其他类型的数据库的批量操作请参考对应驱动提供的方法来自定义实现

    public virtual void BulkInsert(TEntity[] entities,int? batchSize=1000,Action<object, SqlRowsCopiedEventArgs> copyProcess=null, string conn = null)
            {
                TDbContext _context = GetContext(conn);
                var connection = (SqlConnection)_context.Database.Connection;
                connection.Open();
                Type type = typeof(TEntity);
    
    
                var objectContext = _context.GetObjectContext();
    
                var workspace = objectContext.MetadataWorkspace;
    
               // var mappings = EntityMappingExtensions.GetMappings(workspace, objectContext.DefaultContainerName, type.Name);
    
    
                var tableName = GetTableName<TEntity>(_context);
                var bulkCopy = new SqlBulkCopy(connection) { DestinationTableName = tableName };
    
                // Foreign key relations show up as virtual declared 
                // properties and we want to ignore these.
                var properties = type.GetProperties().Where(p => !p.GetGetMethod().IsVirtual).ToArray();
                var table = new DataTable();
                foreach (var property in properties)
                {
                    Type propertyType = property.PropertyType;
    
                    // Nullable properties need special treatment.
                    if (propertyType.IsGenericType &&
                        propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                    {
                        propertyType = Nullable.GetUnderlyingType(propertyType);
                    }
    
                    // Since we cannot trust the CLR type properties to be in the same order as
                    // the table columns we use the SqlBulkCopy column mappings.
                    table.Columns.Add(new DataColumn(property.Name, propertyType));
                    var clrPropertyName = property.Name;
                    var tableColumnName = property.Name;
                    // var tableColumnName = mappings[property.Name];
                    bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(clrPropertyName, tableColumnName));
                }
                
                // Add all our entities to our data table
                foreach (var entity in entities)
                {
                    var e = entity;
                    table.Rows.Add(properties.Select(property =>
                       EntityMappingExtensions.GetPropertyValue(property.GetValue(e, null))).ToArray());
                }
                if (batchSize.HasValue)
                {
                    bulkCopy.BatchSize = batchSize.Value;
                }
                if (copyProcess != null)
                {
                    bulkCopy.SqlRowsCopied += new SqlRowsCopiedEventHandler(copyProcess);
                }
                // send it to the server for bulk execution
                bulkCopy.WriteToServer(table);
    
                connection.Close();
            }
    
    
            private string GetTableName<T>(TDbContext context) where T : class
            {
                Type t = typeof(T);
                var attributes=t.GetCustomAttributes(typeof(TableAttribute), true);
                if (attributes.Length > 0)
                {
                   return t.GetTypeInfo().GetCustomAttributes<TableAttribute>().FirstOrDefault().Name;
                }
                return t.Name;
                //var dbSet = context.Set<T>();
                //var sql = dbSet.ToString();
                //var regex = new Regex(@"FROM (?.*) AS");
                //var match = regex.Match(sql);
                //return match.Groups["table"].Value;
            }

     后续会再补充批量更新,批量删除的方法,区别新增操作,更新和删除是通用于MySql,Oracle,SqlServer(暂时提供这三种数据库),会动态创建sql来实现,用户不必再手写sql或者依赖其他库了

  • 相关阅读:
    要看的博客
    sleep(0)的妙用
    Spring Cloud:Eureka的多网卡IP选择问题
    SpringBoot整合swagger
    springboot整合redis(注解形式)
    RSA非对称加密
    java split(regex,limit) 使用记录
    windows git支持arc命令
    eclipse安装反编译插件
    使用@Validated分组遇到的坑
  • 原文地址:https://www.cnblogs.com/RexSheng/p/10928441.html
Copyright © 2011-2022 走看看