多个存储库共享相同的上下文,调用savechanges操作

时间:2019-02-26 22:40:22

标签: c# entity-framework asp.net-web-api repository-pattern

我通过以下方式具有Web API架构:

控制器->服务->存储库

依赖项通过构造函数注入模式使用Unity框架注入。

我的项目中有类似的内容:

public class OrderService : IOrderService
{
    private readonly IOrderRepo _orderRepo;
    private readonly IProductRepo _prodRepo;

    public OrderService(IOrderRepo orderRepo, IProductRepo prodRepo)
    {
        _orderRepo = orderRepo;
        _prodRepo = prodRepo;
    }

    public void DoSomething()
    {
        _orderRepo.Update();
        _prodRepo.Insert();
    }
}

public class OrderRepo : IOrderRepo
{
    private readonly CreditPortalContext _context;

    public OrderRepo(MyContext context)
    {
        _context = context;
    }

    public void Update()
    {
        //Do something
        _context.SaveChanges();
    }
}

public class ProductRepo : IProductRepo
{
    private readonly CreditPortalContext _context;

    public ProductRepo(MyContext context)
    {
        _context = context;
    }

    public void Insert()
    {
        //Do something
        _context.SaveChanges();
    }
}

现在,OrderService正在调用两个不同的存储库方法来执行某些数据库操作。

我想要的是,如果在_prodRepo.Insert();方法中失败了,它也应该回滚_orderRepo.Update();调用。

我在这个项目中太过分了,因此目前无法执行主要的体系结构更改。同样,context对象仅实例化一次。(使用Unity HierarchicalLifetimeManager

反正我能做到吗?

1 个答案:

答案 0 :(得分:0)

这根本不是一个理想的情况,恐怕您将不得不变得很有创造力。

您不能真正回滚已经提交的语句,但是您可以做其他事情。

所以情况是这样的:您有2个电话,分别是A和B。

呼叫A成功提交。呼叫B失败,您想回滚A。

我的建议是对不同的表执行第一次提交。

在数据库中创建表的副本,然后在该数据库中提交数据。如果B成功,则发出另一个命令以将数据传输到应该在其中的主表中。如果B失败,那么您只需从第二个表中删除数据,并且主表保持不变。

这可以通过存储过程来完成,您可以调用该存储过程,为它提供记录的ID,然后使用第二个表中的行对主表进行更新。您可以轻松地从实体框架中调用存储过程,这样就不会出现问题。

因此,最重要的是,使用临时存储空间,仅在第二次呼叫成功时才移动数据