代码之家  ›  专栏  ›  技术社区  ›  aqwert

存储库是否应该在Entity Framework 1.0中使用相同的上下文实例

  •  2
  • aqwert  · 技术社区  · 15 年前

    我已经开始研究我正在做的一个项目的实体框架,并通过存储库模式对其使用BLL。据我所知,我应该为每个实体创建一个存储库,以便

    public class UserRepository : IRepository<User>
    { ... }
    

    public class AccountRepository : IRepository<Account>
    { ... }
    

    在我看到的示例中,通常的做法是在using语句中创建实体上下文,并在其中执行get、updates和save等操作。

    using(var ctx = new AppEntities()
    {
        //do whatever
        ctx.SaveChanges();
    }
    

    对于对存储库的简单访问,这是可以的,但是如果我想在BYBLL中的2个(或更多)存储库之间构建一个交互呢。。。

    public void SaveSomethingMoreComplex()
    {
        //BLL here stuff like validation etc
    
        _userRepository.GetSomeData();
        _accountRepository.SaveSomeData(account);
        _userRepository.SaveSomeMore(user);
    
        // Probably should have one final save that affects both repositories???
        // Should be in a transaction scope also?
    }
    

    最好还是用同样的方法 AppEntities 两个存储库的实例?

    如果我使用同一个实例,那么将其注入到存储库的构造函数中并使其在应用程序的生命周期内保持有效是安全的,还是我所看到的示例倾向于在单个方法调用中创建和处置的原因?

    谢谢你的帮助。

    2 回复  |  直到 15 年前
        1
  •  3
  •   ckramer    15 年前

    在处理存储库模式时,这实际上并不是一个不寻常的问题,归根结底,它提供了一种显式管理工作单元生命周期的方法(在实体框架的情况下,就是您的上下文)。

    SaveChanges (或者不管实体框架是什么),这会将更改应用到您在请求过程中遇到的所有实体。

    在windows/服务上下文中,您可能需要为您的单元或工作设置某种明确的生命周期管理,这样您就可以根据您正在做的事情来定义UoW的范围。我倾向于喜欢 对话 包装UoW操作的隐喻,这意味着我可以使用以下内容:

    using(Conversation.Start())
    {
        // mess with the entities
    } // Dispose on the object returned from Start will 
      // Save Changes and close the session
    

    当然,这是掩盖了一些异常管理的东西在那里,你会希望有这样的情况下,你可以回滚失败的变化。

    Conversation.Start()

    希望这有帮助。

        2
  •  0
  •   Paul Mendoza    15 年前

    如果我要努力向存储库添加新功能,那么我以后可能想要的是在实体本身上提供这些功能,这样我就创建了包含这种业务逻辑的部分类。这样我就可以执行ShoppingCart.AddProduct(intid)之类的操作,并在分部类中执行逻辑。

    另一个常见的场景是创建一次性视图模型。这实际上是我的首选。

    http://blogs.msdn.com/b/dphill/archive/2009/01/31/the-viewmodel-pattern.aspx

    只需记住,实体框架中的实体已经是数据源的抽象,或者可能与LINQ到SQL不同,LINQ到SQL是数据源的一对一映射。