views:

119

answers:

1

I'm storing some data using NHibernate, and I need to insert huge amount of data as a part of this action - i.e. in the same transaction. Code looks like this:

using (ISession session = NHibernateHelper.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
    session.SaveOrUpdate(something);
    // ...


    SqlBulkCopy bulkCopy = new SqlBulkCopy(
    (SqlConnection)session.Connection,
    SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.FireTriggers,
    ???transaction???
    );
    //...

    transaction.Commit();
}

I know that I could use TransactionScope or do it otherwise. But I insist on this pattern. Let's pretend that for the sake of independent DB access (if I extract and inject arbitrary bulk insert operation). Is there a way how to get SqlTransaction instance out of NHibernate.ITransaction?

Thanks

A: 

Check this post from Ayene:
http://ayende.com/Blog/archive/2009/08/22/nhibernate-perf-tricks.aspx

He shows how you can do that using both options either NHibernate StatelessSession or SqlBulkCopy. It shows a sample code like this:

    var dt = new DataTable("Users");
    dt.Columns.Add(new DataColumn("Id", typeof(int)));
    dt.Columns.Add(new DataColumn("Password", typeof(byte[])));
    dt.Columns.Add(new DataColumn("Username"));
    dt.Columns.Add(new DataColumn("Email"));
    dt.Columns.Add(new DataColumn("CreatedAt", typeof(DateTime)));
    dt.Columns.Add(new DataColumn("Bio"));

    for (int i = 0; i < count; i++)
    {
        var row = dt.NewRow();
        row["Id"] = i;
        row["Password"] = Guid.NewGuid().ToByteArray();
        row["Username"] ="User " + i;
        row["Email"] = i + "@example.org";
        row["CreatedAt"] =DateTime.Now;
        row["Bio"] =  new string('*', 128);
        dt.Rows.Add(row);
    }

using (var connection =
 ((ISessionFactoryImplementor)sessionFactory).ConnectionProvider.GetConnection())
{
    var s = (SqlConnection)connection;
    var copy = new SqlBulkCopy(s);
    copy.BulkCopyTimeout = 10000;
    copy.DestinationTableName = "Users";
    foreach (DataColumn column in dt.Columns)
    {
        copy.ColumnMappings.Add(column.ColumnName, column.ColumnName);
    }
    copy.WriteToServer(dt);
}
Mohamed Meligy
Sorry but I can't see an answer to Transaction problem. Creating an SqlBulkCopy instance isn't a problem.
Elephantik