实体框架/工作单元/存储库体系结构

时间:2015-12-14 11:32:27

标签: entity-framework repository-pattern unit-of-work

我正在创建我的第一个EF 6 Code第一个应用程序。 StackOverflow帮助了我很多问题。然而,信息隐藏仍然困扰着我。

在创建将操纵数据库的POCO实体类之后,我创建了Repository<T>类(和接口),隐藏了使用DbSet<T>的事实,以及一个UnitOfWork类。围绕DbContext和存储库的包装器。

下面我将介绍工作单元/存储库模式的摘要。最终会导致这个问题:

DbSet使用的原始实体对象会暴露出比我想要公开的更多成员,例如外键。我应该公开用于创建DbSet对象的原始实体类,还是应该包含用于CRUD数据库中实体的其他类/接口。

为了描述问题,我将常用的示例与博客和帖子一起使用,例如:MSDN Code First to a new database

public class Blog 
{ 
    public int BlogId { get; set; } 
    public string Name { get; set; } 

    public virtual List<Post> Posts { get; set; } 
} 

public class Post 
{ 
    public int PostId { get; set; } 
    public string Title { get; set; } 
    public string Content { get; set; } 

    public int BlogId { get; set; } 
    public virtual Blog Blog { get; set; } 
}

在设计方面:博客有零个或多个帖子。博客和帖子之间存在一对多的关系。

该框架将创建两个数据库表:一个包含Blogs,另一个包含Posts。每个帖子都有一个外键给它所属的博客。

DbContext

public class BlogContext: DbContext
{
    public virtual DbSet<Blog> Blogs {get; set;}
    public virtual DbSet<Post> Posts {get; set;}
}

IRepository旨在隐藏使用DbSet

public interface IRepository<T> where T: class ...
{
    T GetById(int id);
    void Insert(T entity);
    void Update(T entity);
    void Remove(T entity);
    ...
}

public interface IUnitOfWork : System.IDisposable
{
    IRepository<Blog> Blogs {get;}
    IRepository<Post> Posts {get;}
    void Commit();
}

到目前为止,这么好,相当简单,并根据几个关于这个主题的帖子。帮助了我很多的是Implementing a Data Access Layer with Entity Framework 6.1

问题是通常模式的描述在此处停止。为了能够使用它,我需要一个BlogControl类,它代表我的客户端的接口。该界面(a.o.)具有为博主添加博客和帖子的功能。我的第一枪就是:

public interface IBlogControl
{
     void CreateBlog(Blog blog);  // create a Blog without Posts
     void AddPost(Post post);     // create a post for the blog with Post.BlogId
     ...
}

这些函数将创建一个工作单元,访问存储库以更改序列化数据并提交以保存所有更改。

困扰我这是因为我将BlogPost暴露给了外部世界,这允许不受欢迎的使用。

例如,人们可以创建一个附有多个帖子的博客,或者添加一个与BlogId不对应的博客的帖子。阻止这种情况的一种方法是不公开BlogPost,但是只显示我想要公开的属性和方法的接口IBlogIPost。 / p>

然而,这样做的缺点是人们可以设计自己的博客/帖子类来实现IBlog / IPost,这样就必须将所有数据复制到我自己隐藏的Blog / {{ 1}}对象。

另一种方法是在更改存储库之前检查是否满足所有先决条件。

然而,这些方法效率很低。

所以问题:在使用工作单元/存储库模式时,它是否意味着公开构成我的数据库的原始实体类?我应该只将接口暴露给我想要公开的属性吗?或者我应该提供不公开原始实体类的函数吗?

0 个答案:

没有答案