存储库模式中的可重用模型

时间:2016-05-02 11:53:17

标签: c# entity-framework design-patterns repository-pattern

我最近遇到过多个数据库类型应该可以交换的问题。我的解决方案是存储库模式。 拥有这样的模型。

class Book {
    public string Title { get; set; }
    public virtual Author Author { get; set; }
}
class Author {
    public string Name { get; set; }
    public virtual ICollection<Book> Books { get; set; }
}

将这两个类作为我的模型。 以及我的存储库中的以下方法。

class AuthorRepository {
    IEnumerable<Author> GetAll() {
        return Context.Set<Author>().ToList();
    }
}

现在我遇到了一些问题。首先是使用像这样的存储库。

using(var unitOfWork = new UnitOfWork(new MyContext())) {
    MyObservableCollection = new ObservableCollection<Author>(unitOfWork.Authors.GetAll());
}

如果我尝试访问作者模型中的书籍,我会得到一个ObjectDisposedException。这很明显,因为书籍只能在DbContext中访问,因此该属性实际上只能在存储库内使用而不能在外部使用。

现在我的第二个问题是,当我想从实体框架更改为另一个持久性框架时,虚拟方法将无法工作(因为据我所知),这仅用于实体框架。

上面显示的设置是我如何看到几乎无处不在实现的存储库模式,但是当我需要在需要更改持久性框架时需要更改模型时,我看不到模式中的用法。

我的修复方法如下。

class Author {
    public string Name { get; set; }
}
class EntityFrameworkAuthor : Author {
    public virtual ICollection<Book> Books { get; set; }
}

EF作者只会在存储库中使用,而作者将被返回到业务层。

现在回答我的问题。

  1. 如果我希望能够轻松切换框架(我认为存储库模式适用于),上面显示的方法是否正确使用存储库模式。
  2. 我的修复是改善现有模特的好方法吗?或者它是否以某种方式打破了模式?
  3. 如果不是,我将如何使我的模型可重用于不同的持久性框架。

1 个答案:

答案 0 :(得分:0)

我认为将你的模型分成两部分并不是一个好主意。就个人而言,我总是认为业务逻辑完全没有意识到持久性逻辑。

您可以通过应该以这种方式使用的存储库模式来实现:您只使用基本方法创建存储库类,然后根据需要添加新方法。 原因是您希望每个存储库都是持久层用于加载数据的机制的抽象。 (这是我发现有关存储库模式的有用的link

我的意思是从业务层的角度来看,用于加载的方法,例如,“所有在1974年写过书的作者”可以在您的代码中实现,如存储过程或其他一切;只要请求该组数据的业务对象获得它想要的东西,它就不会(也不应该)关心。

然而,使用您的解决方案,您可以让域对象了解数据的访问方式。 就个人而言,如果将来需要能够更改ORM,我宁愿使用FacadeActorRepository,它使用一个具体的实现EfActorRepository,您可以在更改ORM时切换它。

至于延迟加载问题,在评论中以plalx为主题,(引用)

  

“如果数据未在业务逻辑条件下用于保护   它所属的聚合(数据集群)的状态   数据本身就可以存在,那么就不应该聚合“

这意味着如果作者真的需要一个书籍列表,你不应该允许它被延迟加载,但是你应该在创建完成作者对象后立即加载它。

我希望这会有所帮助:)