【问题标题】:Repositories / Lazy Loading / Persistance存储库/延迟加载/持久性
【发布时间】:2011-04-12 08:51:20
【问题描述】:

我在存储库模式方面遇到了一些问题。或者也许只是一些不清楚的点。为了解决这些问题,我有一个包含两个实体聚合的简单示例域。

public class Category
{
  string Name {get;set;}
  Category Parent {get;set;}
  IList<Category> Children {get;set;}
}

public class Transaction
{
  Category Owner {get;set;}
  string Name
  ... bla bla
}

在这个特定的领域模型中,这两个不形成一个单一的聚合。因此,我为这两个实体中的每一个提供了两个标准的 IRepository 实现。

问题一:在处理验证时,例如删除类别,存储库需要进行关系检查。存储库与其他存储库对话(并因此被注入引用)并生成错误,从而使其与其他层保持整齐断开,或者他们是否将其委托给数据库层,这是一种常见的做法吗?

问题二:同样,在更新实体(聚合)时,通常需要对各个组件进行保存/更改/删除验证。大概只有当您有一个工作单元缓冲更改并且仅在所有验证成功时才提交时,这才是合理可行的?

问题三:不使用延迟加载时,加载单个类别会导致加载整个对象树。要限制这一点,唯一真正的选择是在您的实体中实现延迟加载和/或更改跟踪?

【问题讨论】:

  • 删除存储库模式。不要试图拿起你不能携带的东西。如果 rdbms 在下面,抽象持久性几乎是不可能的。

标签: design-patterns domain-driven-design


【解决方案1】:

对于您提出的所有三个问题,我建议您实施 UnitOfWork 模式。我通常实现 IUnitOfWork 这是我的存储库的一部分。当我想使用不止一个存储库时,我将(相同的)UnitOfWork 注入到我想要使用的所有存储库中(这只是我喜欢的方式之一)。然后,当所有工作完成后,我在我的 UnitOfWork 上调用 Commit(),它会在实体框架上下文中保存更改。 UnitOfWork 是实体框架上下文的包装器

问题一:关系检查由数据库完成。如果出现故障,实体框架将抛出​​异常,您应该在更高的应用层处理它,让我们将其称为服务层,您可以在其中使用 UnitOfWork。

问题二:使用UnitOfWork模式。

问题三:如果不想加载整个对象树,应该使用延迟加载。

存储库:

    public interface IRepository<T>
{
    IUnitOfWork UnitOfWork { get; set; }
    IQueryable<T> All();
    void Delete(T item);
    void Save(T item);
    void Update(T item);
    IQueryable<T> Find(Func<T, bool> expression);
    void Attach(T item);        
}

工作单元:

    public interface IUnitOfWork : IDisposable
{
    ObjectContext Context { get; set; }
    void Commit();
    bool LazyLoadingEnabled { get; set; }
    bool ProxyCreationEnabled { get; set; }
    string ConnectionString { get; set; }
}

或者这里是 UnitOfWork 模式的非常简单的实现,可以帮助您入门(它与我描述的 UnitOfWork 包含的存储库有点不同,我的存储库是相反的......)。

【讨论】:

  • 您的答案非常适合 EF 框架。但是,如果我的数据库层甚至不进行关系检查怎么办。比如一个简单的 DAL 使用 MyISAM MySQL 表?我不能将它委托给 EF 层。我什至不知道在验证的情况下是否会有 EF 层。并且在关注点分离的情况下,验证是否应该 - 知道 - 持久层的类型?
  • 你的数据库支持主键和外键吗?如果没有,那么使用其他一些,但我怀疑它没有。所有基本数据库都有关系检查。可能是你的交易?
  • 不,但是说,例如,实体只是存储在序列化的二进制文件中。验证是否允许删除,是否允许保存不应该知道存储,对吗?它违反了 SoC。
  • 好吧,如果是这种情况,您的存储库实现应该处理关系 chcks。然后应该有更高的级别 - 一项可以将 UnitOfWork 付诸实践的服务。不知道任何关于存储库实现的级别。
  • 嗯。我正在以错误的方式思考它。在使用某种形式的 UoW 时,为了验证目的,存储库相互交谈并没有错……但这取决于存储库的实现。域的其余部分并不关心如何处理它。除了保持数据库有效是存储库的责任。
猜你喜欢
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
相关资源
最近更新 更多