今天遇到在ef框架下新增2W的操作,結果用常規的方法,:“ db.SaveChanges();” 直接就等死了
然後去網上找了一下:
- A1:EntityFramework.Extended 找了這個dll,這dll是在ef做拓展,結果引用到方案裏面點不出方法,不知道網上那些人是怎麼搞出來的===》就棄用了
- A2:Z.EntityFramework.Extended 這個需要收費,而且破解很麻煩==》就棄用了
- A3:SqlBulkCopy,這個是System.Data.SqlClient的一個密封類,不需要引用其他的dll,看網上的評測效果不過,就使用這個==》使用
具體操作代碼如下,拿過去可以直接使用,對網上的一些做了一些調整:
/// <summary>
/// 批量插入
/// </summary>
/// <param name="conn"></param>
/// <param name="list">源數據</param>
internal static void BulkCopy<T>(string strconn, IEnumerable<T> list)
{
var dt = list.ToDataTable();
using (SqlConnection conn = new SqlConnection(strconn))
{
conn.Open();
using (var tran = conn.BeginTransaction(IsolationLevel.ReadCommitted))
{
using (var sqlbulkcopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, tran))
{
sqlbulkcopy.DestinationTableName = dt.TableName;
for (var i = 0; i < dt.Columns.Count; i++)
{
sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);
}
try
{
sqlbulkcopy.BulkCopyTimeout = 180;
//寫入數據庫表?dt?是數據源DataTable
sqlbulkcopy.WriteToServer(dt);
tran.Commit();
}
catch (Exception ex)
{
tran.Rollback();
throw ex;
}
finally
{
tran.Dispose();
}
}
}
}
}
/// <summary>
/// List轉DataTable
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">集合</param>
/// <returns></returns>
public static DataTable ToDataTable<T>(this IEnumerable<T> list)
{
var type = typeof(T);
var properties = type.GetProperties().ToList();
var newDt = new DataTable(type.Name);
properties.ForEach(propertie =>
{
Type columnType;
if (propertie.PropertyType.IsGenericType && propertie.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
columnType = propertie.PropertyType.GetGenericArguments()[0];
}
else
{
columnType = propertie.PropertyType;
}
newDt.Columns.Add(propertie.Name, columnType);
});
foreach (var item in list)
{
var newRow = newDt.NewRow();
properties.ForEach(propertie =>
{
newRow[propertie.Name] = propertie.GetValue(item, null) ?? DBNull.Value;
});
newDt.Rows.Add(newRow);
}
return newDt;
}