存储库/延迟加载/持久性

时间:2011-04-12 08:51:20

标签: design-patterns domain-driven-design

我在存储库模式方面遇到了一些问题。或许只是一些不明确的观点。为了这些问题,我有一个带有两个实体聚合的简单示例域。

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 实现。

问题一:在处理验证时,例如删除类别,存储库需要进行关系检查。通常的做法是将存储库与其他存储库进行通信(并因此注入引用)并生成错误,从而使其与其他层完全断开连接,还是将其委托给数据库层?

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

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

1 个答案:

答案 0 :(得分:4)

对于你的所有三个问题,我建议你实现UnitOfWork模式。我ususaly实现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);        
}

的UnitOfWork:

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

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