Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 混合Nhibernate和ADO事务?_C#_Sql Server_Nhibernate_Repository Pattern - Fatal编程技术网

C# 混合Nhibernate和ADO事务?

C# 混合Nhibernate和ADO事务?,c#,sql-server,nhibernate,repository-pattern,C#,Sql Server,Nhibernate,Repository Pattern,我有一个很奇怪的要求,因为我继承了一个代码库。DAL基于存储库模式,但是有些存储库使用SqlConnection/SqlCommand和直接SQL和参数化查询进行编码,有些存储库使用NHibernate进行编码 我需要执行一系列的数据操作,这些操作需要来自两个部门的存储库,如果在过程中的任何阶段都失败,则需要回滚。最好的办法是什么 System.Data公开一个IDbTransaction和一个NHibernate ITransaction,这两个是否兼容?我是否可以同时运行这两个事务,然后在出

我有一个很奇怪的要求,因为我继承了一个代码库。DAL基于存储库模式,但是有些存储库使用SqlConnection/SqlCommand和直接SQL和参数化查询进行编码,有些存储库使用NHibernate进行编码

我需要执行一系列的数据操作,这些操作需要来自两个部门的存储库,如果在过程中的任何阶段都失败,则需要回滚。最好的办法是什么


System.Data公开一个IDbTransaction和一个NHibernate ITransaction,这两个是否兼容?我是否可以同时运行这两个事务,然后在出现问题时回滚它们?TransactionScope会在这种情况下帮助我吗

nhibernate也支持sql语句

我似乎记得这个方法

NHibernateSession.CreateSQLQuery,它返回IQuery(实际上它是SQLQuery

您可以继续调用方法ListUniteResult

通常,编码人员喜欢使用名为Hashtable的k-v类


您可以在Nhibernate中使用ITransaction。

Nhibernate也支持sql语句

我似乎记得这个方法

NHibernateSession.CreateSQLQuery,它返回IQuery(实际上它是SQLQuery

您可以继续调用方法ListUniteResult

通常,编码人员喜欢使用名为Hashtable的k-v类


您可以在Nhibernate中使用ITransaction。

TransactionScope将创建一个钩子,所有通过ADO.Net的组件都将使用该钩子。因为所有的ORM都通过ADO.Net,所以它们都会隐式地使用TransactionScope。NHibernate、Linq、EF或您选择的任何ORM之类的代码都无法抑制这种情况,除非它们通过显式地用新范围覆盖当前范围来显式抑制TransactionScope


问题可能是由于多个连接注册到服务器上,导致事务升级到服务器上的分布式事务。这是一个容易理解的主题,取决于SQL Server/.Net版本,请参阅。

TransactionScope将创建一个钩子,所有通过ADO.Net的组件都将使用该钩子。因为所有的ORM都通过ADO.Net,所以它们都会隐式地使用TransactionScope。NHibernate、Linq、EF或您选择的任何ORM之类的代码都无法抑制这种情况,除非它们通过显式地用新范围覆盖当前范围来显式抑制TransactionScope


问题可能是由于多个连接注册到服务器上,导致事务升级到服务器上的分布式事务。这是一个很难理解的主题,取决于SQL Server/.Net版本,请参阅。

我假设您希望有类似于以下内容的代码:

public class SomeService
{
    private readonly IRepositoryA _repoA;
    private readonly IRepositoryB _repoB;

    public void DoStuff(EntityA someEntityA, EntityB someEntityB)
    {
        try 
        {
             _repoA.Save(someEntityA);
             _repoB.Save(someEntityB);
             // commit all stuff here

        }
        catch
        {
             // rollback all stuff here
        }
    }
}
如果确实如此,那么您需要有某种UnitOfWork抽象,这两个存储库都依赖于它,并且可以为它们各自的事务上下文引用它。如果两个回购协议都使用Nhibernate或IDbConnection/DbTransactions,则会容易得多,但由于存在混合,您将不得不做更多的工作

您需要创建一个包含IDB事务和ITransaction的“GenericTransaction”,并让您的工作单元拥有一个创建新GenericTransaction的方法

GenericTransaction上的提交/回滚将对这两个事务执行相应的操作


要做到这一点,你将不得不重构你现有的回购相当多。。。但我不推荐任何其他方式。

我假设您希望有类似于以下内容的代码:

public class SomeService
{
    private readonly IRepositoryA _repoA;
    private readonly IRepositoryB _repoB;

    public void DoStuff(EntityA someEntityA, EntityB someEntityB)
    {
        try 
        {
             _repoA.Save(someEntityA);
             _repoB.Save(someEntityB);
             // commit all stuff here

        }
        catch
        {
             // rollback all stuff here
        }
    }
}
如果确实如此,那么您需要有某种UnitOfWork抽象,这两个存储库都依赖于它,并且可以为它们各自的事务上下文引用它。如果两个回购协议都使用Nhibernate或IDbConnection/DbTransactions,则会容易得多,但由于存在混合,您将不得不做更多的工作

您需要创建一个包含IDB事务和ITransaction的“GenericTransaction”,并让您的工作单元拥有一个创建新GenericTransaction的方法

GenericTransaction上的提交/回滚将对这两个事务执行相应的操作


要做到这一点,你将不得不重构你现有的回购相当多。。。但我不推荐任何其他方法。

您可以简单地尝试一下。。。或者谷歌…你可以简单地尝试一下。。。或者谷歌。。。