BulkSqlCopy 批量导入数据(Ef支持)

时间:2021-08-21 13:03:17

Ado.net对批量数据的支持相信大家都已经非常熟悉。再此就不在多说,就当是给自己备个份,没办法,这个方法太好用了。

  public static void BulkCreate( string tableName,bool IsGuid=true)
{
string sql = string.Format("select * from {0}",tableName);
DataTable dt = new DataTable();
using (SqlDataAdapter da = new SqlDataAdapter(sql, constr))
{
da.Fill(dt);
}
if (dt != null && dt.Rows.Count > )
{
using (var tran = db.Database.BeginTransaction())
{
try
{
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(db.Database.Connection.ConnectionString))
{ //每1W条一个事物
sqlBulkCopy.BatchSize = ;
sqlBulkCopy.BulkCopyTimeout = ;
sqlBulkCopy.DestinationTableName = string.Format("dbo.{0}", tableName);
sqlBulkCopy.BatchSize = dt.Rows.Count;
if (!IsGuid)
{//如果主键不是Guid,是Int自增类型,这个时候就需要注意了,直接忽略第一列,所以for循环从1开始。
for (int i = ; i < dt.Columns.Count; i++)
{
sqlBulkCopy.ColumnMappings.Add(i, i);
}
}
sqlBulkCopy.WriteToServer(dt);
tran.Commit();
}
}
catch
{
tran.Rollback();
} }
}
}

上面简单实现了下,如果是EntityFrameWork 怎么办,不想让代码层面出现不和谐的红色sql语句。很简单,只需要三个参数,一个是表名(可以根据映射的实体特性[Attribute]获得),一个是列名,最后是列值,后面的两个自然是根据反射获得了。下面简单实现下,只当做参考,请原谅:

        public void BulkCreate<T>(List<T> list) where T : new()
{
DataTable dt = new DataTable();
Type type = typeof(T);
string tableName = GetTableName(type);
PropertyInfo[] propes = type.GetProperties();
foreach (var prop in propes)
{
dt.Columns.Add(prop.Name);
}
//再此是假设数据库列与对象列一致 没有判断列属性,如果有列属性的话 ,就需要再多一次判断
foreach (var entity in list)
{
DataRow row = dt.NewRow();
foreach (DataColumn col in dt.Columns)
{
foreach (var prop in propes)
{
if (!col.ColumnName.Equals("id", StringComparison.InvariantCultureIgnoreCase))
{
if (prop.Name.Equals(col.ColumnName, StringComparison.InvariantCultureIgnoreCase))
row[col.ColumnName] = prop.GetValue(entity);
}
} }
dt.Rows.Add(row);
}
if (dt != null && dt.Rows.Count > )
{
using (var tran = db.BeginTransaction())
{
try
{
BulkCopy(dt, tableName);
}
catch (Exception e)
{
tran.Rollback();
}
tran.Commit();
} }
} private bool BulkCopy(DataTable dt, string name)
{
//string constr = System.Configuration.ConfigurationManager.ConnectionStrings["BingStampAzureContext"].ToString();
string constr = db.Database.Connection.ConnectionString;
SqlBulkCopy sqlBulkCopy = null;
try
{
using (SqlConnection conn = new SqlConnection(constr))
{
sqlBulkCopy = new SqlBulkCopy(constr);
sqlBulkCopy.BulkCopyTimeout = ;
sqlBulkCopy.DestinationTableName = string.Format("dbo.{0}", name);
sqlBulkCopy.BatchSize = dt.Rows.Count;
sqlBulkCopy.WriteToServer(dt);
} return true;
}
catch (Exception ex)
{
return false;
}
finally
{
if (sqlBulkCopy != null) sqlBulkCopy.Close();
}
} public string GetTableName(Type type)
{
object[] attributes = type.GetCustomAttributes(false);
if (attributes.Length > )
{
var attribute = (System.ComponentModel.DataAnnotations.Schema.TableAttribute)attributes[];
return attribute.Name;
}
else
return string.Empty;
}

下面给个对象调用下 :

       [Table("Student")]
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string Remark { get; set; }
}

具体测试略。。