簡體   English   中英

使用IRepository的C#共享事務和NHibernate

[英]C# Shared Transactions and NHibernate using IRepository

我正在考慮使用NHibernate實現IRepository模式,但我有一個問題,就是我無法回答搜索網絡問題。

假設我有3個存儲庫,PersonRepository,PersonAddressRepository和PersonAccountRepository。 現在,假定業務邏輯規定存在一個調用PersonRepository.Deactivate(),PersonAddressRepository.Deactivate()和PersonAccountRepository.Deactivate()的“停用Person”過程。

我希望能夠做一些類似的事情。

using (ITransaction transaction = session.BeginTransaction()) { 
    session.Update(Person);
    session.Update(PersonAddress);
    session.Update(PersonAccount);
}

因此,如果這些更新中的任何一個失敗,整個過程將在數據庫中回滾。 現在,我對NHibernate的了解是,您只能為每個對象創建一個Session。

var cfg = new Configuration();
cfg.Configure();
cfg.AddAssembly(typeof(Person).Assembly);
ISessionFactory sessionFactory = cfg.BuildSessionFactory();
using (ISession session = sessionFactory.OpenSession()) {
    using (ITransaction transaction = session.BeginTransaction()) {
    session.Save(Person);
}

這是正確的還是我弄錯了? 關於多表更新和關於NHibernate的事務的最佳實踐是什么?

提前致謝。

您不應在存儲庫或其他“波紋管”中創建事務。 事務由應用程序邏輯定義。 這是我在事務處理中看到的最常見的錯誤之一。

我寫了一個交易服務來管理交易:

using (TransactionService.CreateTransactionScope())
{
  repositoryA.DoX();
  repositoryB.DoY();
  TransactionService.Commit();
}

存儲庫正在通過服務從開放事務中獲取會話:

TransactionService.Session.CreateQuery("...");

根據您的環境,您需要使其更加復雜。 例如,會話可能對業務邏輯不可見,應將其放置到另一個接口等上。

我以為NHibernate可以理解System.Transactions.TransactionScope類。 你為什么不使用它?

您可以做的一件事-這就是我現在的做法-將應該用於存儲庫實例的ISession實例傳遞給它。

將來,我將要做的是:

  • 我有一個UnitOfWork類,該類非常通用,是NHibernate的ISession對象的包裝。 此UnitOfWork類不包含“應用程序”或特定於域的方法

  • 在使用NHibernate(和我的UnitOfWork包裝器)的項目中,我將在UnitOfWork類上創建一組擴展方法,如下所示:

     public static class UnitOfWorkExtension` { public static IPersonRepository GetPersonRepository( this UnitOfWork uow) { return new PersonRepository(uow); } public static IAccountRepository GetAccountRepository( this UnitofWork uow ) { return new AccountRepository(uow); } } 

然后,這將允許我執行此操作,例如:

using( var uow = unitOfWorkFactory.CreateUnitOfWork() )
{
     var person = uow.GetPersonRepository().GetPerson (1);
     var accounts = uow.GetAccountRepository().GetAccountsForPerson(person);
}

但是,看看您的示例,我想知道您是否應該為“ PersonAddress”和“ PersonAccount”提供存儲庫。 以我的拙見,在您的示例中, Person是一個“聚合根”,它由一個PersonAddress和一個PersonAccount組成,並且應該有一個PersonRepository處理該Person的聚合根(包括PersonAddress和PersonAccount對象-實際上,它們不是實體但重視對象(如我所見)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM