当前位置: 首页 > 知识库问答 >
问题:

一个DbContext实例跨越多个存储库

钱浩荡
2023-03-14
 builder.RegisterType<MyContext>().As<MyContext>().InstancePerRequest();
 builder.RegisterType<TestRepository>().InstancePerRequest();
 builder.RegisterType<SchoolclassCodeRepository>().InstancePerRequest();
 builder.RegisterType<TestService>().InstancePerRequest();

但是,共享上下文还有其他很好的理由,其中之一(IMHO)是上下文必须跟踪实体的状态,如果您要获得一个实体,处理该上下文,对该实体进行一些修改,然后附加到一个新的上下文,这个新的上下文必须访问数据库,以便它能够计算出该实体的状态。同样,如果您正在处理实体(发票和它们的所有InvoiceItems)的图,那么新的上下文必须获取图中的所有实体来确定它们的状态。

但现在我用这种建筑撞上了单行道!

如果我必须做一个跨越多个存储库的事务怎么办?

using(NorthwindEntities db = new NorthwindEntities())
{
    DbContextTransaction transaction = db.Database.BeginTransaction();

    try
    {
        //insert record 1
        Customer obj1 = new Customer();
        obj1.CustomerID = "ABCDE";
        db.Customers.Add(obj1);
        db.SaveChanges();

        //insert record 2
        Customer obj2 = new Customer();
        obj2.CustomerID = "PQRST";
        db.Customers.Add(obj2);   
        db.SaveChanges();

        transaction.Commit();
    }
    catch
    {
        transaction.Rollback();
    }
}
    null

如何在不更改存储库的情况下在多个存储库上创建事务?

示例我想要的东西:

在我的TestService中,我想大致做以下操作:

public void Save()
{
  // Open Transaction
  // testRepo.Insert();
  // schoolclassCodeRepo.Delete();
  // Commit Transaction
}
    null

更新3解决方案代码

public async Task<bool> DeleteSchoolyearAsync(int id)
{
    using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
    {
        try
        {
            await testRepository.DeleteTestTypes(id);
            await schoolyearRepository.DeleteAsync(id);
            scope.Complete(); // Rollback is done due to using statement...
            return true;

        }
        catch (System.Exception)
        {
            return false;
        }
    }
}

这个代码工作得很好!

共有1个答案

吕淮晨
2023-03-14

您不改变存储库,但您的体系结构中肯定缺少工作单元。这是您为多个存储库共享单个上下文的地方。

将UoW视为DbContext,其中存储库是DBSet。

UoW uow = new UoW( context );

uow.BeginTransaction();

uow.Repository1.... // query, insert, update, delete
uow.Repository2....

uow.Commit();

典型的实现只公开多个存储库:

public class UoW {

   public UoW( DbContext ctx ) {

      this._ctx = ctx;

   }

   private Repository1 _repo1;

   public Repository1 Repo1
   {
      get
      {
          if ( _repo1 == null )
              _repo1 = new Repository1( this._ctx );
          return _repo1;
      }

      ...
 类似资料:
  • 我正在为一个项目制作购物车脚本。购物车已经创建,但现在我正在查询购物车中的产品插入订单表的位置。但是当我这样做的时候,每个产品都有自己的,有没有可能给购物车中的每个产品相同的? 将产品插入订单表的查询: SQL查询如下: 我希望有人能给我一些建议, 提前感谢!

  • 我有一个Java程序,需要在多个类的多个点上从控制台获取用户输入。我试着在每节课上使用一台扫描仪,但当我关闭一台扫描仪时,它会关闭系统。所以我想在整个程序中使用相同的扫描仪。我在主类中打开了扫描仪,但在其他类中如何使用相同的扫描仪?

  • 问题内容: 我想使用两个Git存储库构建一个项目。其中一个包含源代码,而另一个包含构建和部署脚本。 我的问题是我需要一个用于构建和部署项目不同部分(大型项目,多个存储库,相同的构建和部署脚本)的存储库,但是Jenkins似乎无法处理此问题(或者我不知道)不知道/找不到方法)。 问题答案: 更新 现在不建议使用多个SCM插件,因此用户应该迁移到Pipeline插件。 旧答案 是的,詹金斯可以处理。只

  • 我有一个,每个月底运行一次。运行后,它会将一些数据保存到数据库中。 当我扩展应用程序时(例如有2个实例),两个实例都运行计划作业,并且都保存数据,在一天结束时,我的数据库有相同的数据。 所以我希望计划作业只运行一次,而不管云上的实例数量如何。

  • 我有一个小部件链接到我的应用程序中的一个活动。为此,我在我的中链接: