Я храню некоторые данные с помощью 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();
}
Я знаю, что мог использовать TransactionScope или сделать это иначе. Но я настаиваю на этом шаблоне. Давайте притворимся, что ради независимого доступа DB (если я извлекаю и ввожу произвольную объемную операцию вставки). Есть ли путь, как добраться SqlTransaction
экземпляр из NHibernate.ITransaction
?
Спасибо
Проверьте это сообщение от Ayene:
http://ayende.com/Blog/archive/2009/08/22/nhibernate-perf-tricks.aspx
Он показывает, как вы можете сделать это, используя обе опции: NHibernate StatelessSession или SqlBulkCopy. Он показывает пример кода, подобный этому:
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);
}