【问题标题】:EF6 and business logic layerEF6 和业务逻辑层
【发布时间】:2014-11-07 04:04:33
【问题描述】:

我正在尝试掌握如何将 EF 用于即将进行的项目。

目前我有这个代码优先代码:

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; }
}

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

这创建了数据库和表,我已经能够添加博客/发布没有问题。但我对如何围绕 EF 代码优先方法进行结构感到困惑。

BlogPost 是否都应该引用BloggingContext,然后有自己的获取/添加/更新方法?

我是否应该创建单独的 BlogManager / PostManager 类来实际执行获取/添加/更新数据并简单地返回实体对象?

我是否应该创建从 Blog / Post 继承的包含 ​​get / add / update 方法的单独类?

【问题讨论】:

  • 我认为您应该什么都不做,因为您需要的所有内容都已在您的代码示例中到位。 DbContext 中的 DbSet 具有跟踪实体的机制。当您致电 dbContext.SaveChanges() 时,所有跟踪的更改都将进入数据库
  • 您通常希望创建 IBlogRepositoryIPostRepository 接口以及包装您的 BloggingContext 的相应实现。这样你就可以从你的业务逻辑类中抽象出 ORM 的实际实现和使用。

标签: c# entity-framework


【解决方案1】:

Blog 和 Post 是否都应该引用 BloggingContext

不 - 类本身不应绑定到特定来源。它们应该只代表一个实体,并且独立于数据的来源。这样可以更轻松地进行单元测试,因为您可以创建一个完全独立于数据源的博客。

我是否应该创建单独的 BlogManager / PostManager 类来实际执行获取/添加/更新数据并简单地返回实体对象?

是的 - 这通常称为 存储库,因此 BlogRepositoryPostRepository 可能是更好的名称。

由于两者相互依赖,最好创建存储库实现的IBLogRepositoryIPostRepository 接口,这样您就不会紧密耦合存储库。然后,当您查询博客并希望它发布时,BlogRepository 可以将请求链接到 IPostRepository

我是否应该创建从包含 get/add/update 方法的 Blog/Post 继承的单独类?

否 - 因为继承意味着“是”关系 - 并且类保存博客不一定是博客本身。

【讨论】:

  • 感谢您的回复,您的最后一点确实让我思考了如何构建我的应用程序。通常,我可能会将与Blog 相关的所有内容放入单个Blog 类中。例如如果我有一个 UI 函数(例如,返回为 UI 使用而格式化的数据),它将进入 Blog,如果我有一个删除所有没有帖子的博客的函数,它也会进入 Blog。诸如“删除所有没有帖子的博客”之类的内容是否应该进入 BlogRepository 然后单独的 BlogUIclass 用于 UI 功能?
  • 是的——理想情况下,类应该有一个功能:携带数据、存储数据、进行计算、显示数据等都是不同的功能。否则,您最终会得到难以更改、调试、测试、模拟等的庞大类。
  • 把我送进了兔子洞,花了最后 22 小时阅读 SOLID 原则。起初,我认为一个对象应该是 ANTI-OBJECT。但我认为现在使用得当,在需要的地方确实让事情变得容易多了。
【解决方案2】:

DbContext 类可以自己处理所有与数据相关的事情。您不需要在实体类中包含对它们的引用(也不应该,因为DbContext 类打开了数据库连接)。 DbContext 还将自行处理您的基本 CRUD 操作(通过在其上使用 DbSets&lt;T&gt;,这是访问特定表中所有数据的简单方法。

如果您愿意,您还可以在 cmets 中执行上面提到的 @Sergey 并在其上实现存储库接口。我写了一篇关于如何做的博客文章,你可以find here。基本上,您将其设置为具有对 DbContext 类的背景引用的通用存储库,这样您就可以在应用程序代码和数据库逻辑之间建立一个很好的层。

【讨论】:

  • 网址似乎已关闭,@IronMan84。
  • 很奇怪。在 VPN 上总是发生在我身上。请立即尝试。
  • 谢谢@IronMan84,就像一个魅力。谢谢!
  • 感谢您的回复,我认为我的问题措辞不是很好。我的“正常”编码方式是拥有一个Blog 类,它可以完成与博客相关的大部分事情,例如var blog = new Blog(1) 会尝试从数据库加载博客 ID 1,然后我可以更改属性并调用函数来操作 Blog 然后调用 blog.Save() (uses TableAdapters) 将其保存回数据库。我应该使用 EF / DBContext 作为表适配器的替代品吗?或者他们可以成为我的Blog 班级吗? ps,阅读你的博客!
猜你喜欢
  • 2014-09-04
  • 2010-12-18
  • 2011-08-17
  • 2011-12-03
  • 2011-11-26
  • 2017-04-29
  • 2016-08-12
  • 2013-10-27
  • 2013-02-18
相关资源
最近更新 更多