在SqlBulkCopy中使用NHibernate事务

Ele*_*tik 15 c# sql-server nhibernate ado.net transactions

我正在使用NHibernate存储一些数据,我需要插入大量数据作为此操作的一部分 - 即在同一事务中.代码如下所示:

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();
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用TransactionScope或以其他方式使用它.但我坚持这种模式.让我们假装为了独立的DB访问(如果我提取并注入任意批量插入操作).有没有办法让SqlTransaction实例出来NHibernate.ITransaction

谢谢

Mat*_*ght 23

不出所料,Ayende也解决了这个问题,但它非常可笑.

它的要点是你知道你可以IDbCommand在NHibernate事务中登记正常的ADO.NET 实例,如下所示:

var cmd = new SqlCommand ();
if (session.Transaction != null && session.Transaction.IsActive)
    session.Transaction.Enlist (cmd);
Run Code Online (Sandbox Code Playgroud)

SqlBulkCopy不是一个IDbCommand,而且那个特定的构造函数需要一个SqlTransaction(所以你已经在提供者独立性上已经跳过了).所以作弊 - 你的例子可能看起来像这样:

using (var session = NHibernateHelper.OpenSession ())
using (var transaction = session.BeginTransaction ()) {
    using (var cmd = new SqlCommand ()) {
        transaction.Enlist (cmd);

        var bulk = new SqlBulkCopy ((SqlConnection)session.Connection,
                                    SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.FireTriggers,
                                    (SqlTransaction)cmd.Transaction);
    }
    // ...
    transaction.Commit ();
}
Run Code Online (Sandbox Code Playgroud)

毫无疑问,你需要在那里进行一些错误检查,安全演员表等.不幸的是,我不知道有一种更现代/更可怕的方式来做这件事(即使从中得到IDbTransaction一个ITransaction).