Reputation: 1364
I have a static helper method for bulk inserting Entity Framework objects. It works and my unit tests pass but it looks wrong and I can't help but think there must be a better way to do it.
public static void BulkInsert<T>(Entities db, IList<T> list)
{
SqlTransaction transaction = db.Database.CurrentTransaction != null ? db.Database.CurrentTransaction.UnderlyingTransaction as SqlTransaction : null;
if (db.Database.Connection.State != ConnectionState.Open)
{
db.Database.Connection.Open();
}
using (var bulkCopy = new SqlBulkCopy((db.Database.Connection) as SqlConnection, SqlBulkCopyOptions.Default, transaction))
{
//fill a datatable and write to server, this bit works
}
}
It could be called inside a DbContextTransaction
and/or the DbContext.Database
might have done something already so the connection might be open. If you don't explicitly open the connection before creating the bulk copy you get an error:
System.InvalidOperationException: WriteToServer requires an open and available Connection
which is odd, I'd have thought that sqlBulkCopy
would have opened the connection if it had to.
So my question is am I going about this the right way?
Upvotes: 2
Views: 6179
Reputation: 16022
I have used your approach successfully myself.
My feeling is that you should close it again if you opened it.
I would additionally let SqlBulkCopy
handle the transaction itself. I don't think enlisting SqlBulkCopy
into any ambient transaction is a great idea unless your particular scenario absolutely demands it.
public static void BulkInsert<T>(PandaDataContext db, IList<T> list)
{
var mustOpen = db.Database.Connection.State != ConnectionState.Open;
try
{
if (mustOpen)
db.Database.Connection.Open();
using (var bulkCopy = new SqlBulkCopy((db.Database.Connection) as SqlConnection, SqlBulkCopyOptions.Default))
{
}
}
finally
{
if (mustOpen)
db.Database.Connection.Close();
}
}
Upvotes: 4