将多个存储库使用相同的DbContext是明智的吗?

时间:2013-01-31 00:04:59

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

深入了解实体框架和存储库,以便更好地进行测试。想知道这是否明智?

public interface IRepository
{
    int SaveChanges();

    void Dispose();
}

using (MyContext context = new MyContext())
{
    TransactionRepository txns = new TransactionRepository(context); // TransactionRepository implement IRepository
    MappingRepository maps = new MappingRepository(context); // MappingRepositoryimplement IRepository

    SomeCommand command = new SomeCommand(txns, maps);
    command.Execute();
}

每个存储库在逻辑上都是不同的,因此理论上可以在不同的数据源中。目前,他们使用相同的数据库。每个存储库类都实现了IRepository,特别是SaveChanges()以及一些我为简洁起见未展示的查询方法。

使用多个存储库的好习惯是什么?

3 个答案:

答案 0 :(得分:3)

这真的归结为你自己的设计决定。如果您正在关注工作单元模式,那么每个存储库可能都会拥有自己的上下文;主要是因为根据UoW,每个存储库调用应该创建它的上下文,做它的工作,然后处理它的上下文。

还有其他很好的理由来共享一个上下文,其中一个(恕我直言)是上下文必须跟踪一个实体的状态,如果你得到一个实体,处理上下文,对其进行一些修改实体,然后附加到新上下文这个新上下文必须命中数据库,以便它可以找出实体的状态。同样,如果您正在使用实体图表(发票及其所有InvoiceItems),那么新上下文必须获取图表中的所有实体以确定其状态。

现在,如果你正在处理你不能或不能保持状态的网页或服务,那么UoW模式就是暗示的,这是一种普遍接受的“良好做法”。

答案 1 :(得分:2)

+1大猩猩,一些商品点。我想补充以下想法。

在web / mvc场景中,我使用了许多存储库并将Context注入这些存储库。我使用了存储库基类。 我也是在构造函数中使用上下文的UoW类。 工作单元类包含对上下文的所有受支持存储库的引用。我也使用有界的上下文。以下是Julie Lerman关于此主题的示例博客。 http://www.goodreads.com/author/show/1892325.Julia_Lerman/blog

所以是的,使用多个上下文并使用多个存储库是完全合理的。 您甚至可以拥有多个工作单元类,但是同时使用UoW类是另一种讨论。

按要求添加示例代码: 此示例是从基础LuW类继承的几个LuW类之一。 注入要使用的当前状态和DBContext。 (或默认) 存储库是CORE项目的接口。 LuW课程在DAL项目中。

基础LuW就像....

public interface ILuw : ILuwEvent, IDisposable
  {

   IBosCurrentState CurrentState{ get; set; }
   OperationStatus Commit();

   }

Luw Class本身。

namespace XYZ.DAL
{
public class LuwBosMaster : Luw, ILuwBosMaster
{
    public LuwBosMaster(DbContext context, IBosCurrentState currentState)  
    {
       base.Initialise(context,currentState); 
    }
    public LuwBosMaster()
    {

        base.Initialise(GetDefaultContext(), BosGlobal.BGA.IBosCurrentState);
    }
    public static DbContextBosMaster GetDefaultContext()
    {
     return new DbContextBosMaster("BosMaster");
    }

    //MasterUser with own Repository Class
    private IRepositoryMasterUser _repositoryMasterUser;
    public  IRepositoryMasterUser RepMasterUser
    { get { return _repositoryMasterUser ?? (_repositoryMasterUser = new RepositoryMasterUser(Context, CurrentState)); } }

    //20 other repositories declared adn available within this Luw
    // Some repositories might address several tables other single tables only.
    //  The repositories are based on a base class that common generic behavior for each MODEL object

我相信你明白了......

答案 2 :(得分:1)

最重要的是忘记了:多个DbContext实例之间不共享数据库连接。这意味着如果您希望多个存储库位于同一事务中,则必须使用分布式事务。与本地交易相比,这会导致性能下降。