ASP.NET MVC - DbContext的良好实践

时间:2015-04-05 09:53:41

标签: asp.net-mvc entity-framework

我正在使用Entity Framework启动一个新的.NET MVC项目,我正在努力解决一些问题。

  1. 在我的模型中,我有大约150个实体(从数据库生成)。只有一个DbContext是个好主意吗?如果没有,我应该如何划分我的实体?

  2. 如果我有一个DbContext并且我创建了一个实例化数据库上下文对象的类变量(在Controller中),那么这个DbContext会发生什么?它是否在内存中为每个实体创建了单独的空间?在我的情况下,当我有150个实体时,它不会非常有效。我错了吗?

  3. 我将在许多控制器中使用我的DbContext。创建一个MainController(我创建新的DbContext)是一个好主意,它将由其他控制器继承吗?因为这允许其他人访问相同的上下文。

  4. 处理我的DbContext的最佳做法是什么?我已经读过使用依赖注入是一种好习惯。但是通过这种方式,我将不得不为每个控制器注入上下文。哪种依赖注入方式最受欢迎并现在使用?

  5. 真的需要你的建议。它将使我更深入地了解这一发展。

3 个答案:

答案 0 :(得分:5)

  1. 一个DbContext可以。如果您有很多,则只需确保在该上下文中存在所需的所有实体。例如,如果您从数据库及其相关Person检索Address,则PersonAddress必须存在于同一DbContext中。

    我没有尝试过使用多个DbContext实例,但要注意的一件事是,如果在多个上下文中包含相同的表,最终可能会出现类似名称或冲突的类。例如,如果在两个上下文中包含Person,则每个上下文将尝试创建一个名为Person的类。

  2. 创建DbContext时,它只会为您从数据库中检索的数据创建对象。因此,如果您从Person表请求一行,则只会创建一个Person对象。如果您请求100行,则将创建100个实例。

  3. 实际上有两种选择。一,在每个动作中创建一个新实例,完成你的工作,然后保存它。或者,在构造函数中创建一个DbContext并在整个类中重用它。

  4. 这取决于您在第3点中选择的内容。如果将其传递给构造函数,则实现IDisposable并在其中释放它。如果您在每个操作中创建一个新操作,请确保使用using语句处理它。

  5. 对于依赖注入,有很多选项,教程等,关于如何在ASP.NET MVC中执行此操作。我个人使用Autofac和相关的MVC扩展,并将DbContext的新实例传递给每个控制器。

答案 1 :(得分:1)

150个实体不是一个巨大的DbContext,但它高于EF在第一个DbContext的初始化中开始出现性能问题的大小。如果您可以在逻辑上将实体分成责任区域(称为有界上下文),那么您可以考虑使用多个DbContext。此外,您的应用是否需要使用所有这些实体?如果没有,您可以简化一些事情。另请注意,您需要至少使用EF6才能有效地工作,以前版本的Entity Framework存在多个上下文的问题。

使用多个上下文时也必须小心。许多人遇到麻烦是因为他们从一个上下文中获得了一个实体,然后在另一个上下文中调用保存更改,然后不理解为什么他们的更改没有被保存。或者,他们尝试将从一个实体检索到的实体添加到另一个实体,这是您无法做到的。多个上下文会使事情变得更复杂,因此请确保在拆分之前要考虑这种复杂性。

不要担心DbContext使用的内存量,只要您正确处理它。除非您实际从所有表中加载对象,否则内存量将是最小的。

我认为常见的基本控制器是代码味道。它通常是完全没有必要的,它通常最终成为您认为想要分享的每一段代码的倾销场,这违反了单一责任委托人。最重要的是,您无论如何都不应该在控制器中进行数据访问。您应该有一个调用数据访问层的某种服务层或业务层。正确地分离您的顾虑是设计一个好的MVC应用程序的关键部分。

是的,依赖注入是一种很好的做法。我不确定你的意思是什么,必须注入我的所有控制器"。依赖注入的全部意义在于注入依赖关系,因此"必须注意到"让你好像想要避免你想要做的事情。

依赖注入是一个原则。有许多方法可以实现这一原则,您使用哪种方式完全取决于您自己的偏好和要求。我们无法告诉您最好的"最好的"除了确保你遵守原则,而不是特定的技术。

答案 2 :(得分:0)

关于dbcontext问题: 我会使用多个dbcontext(有界上下文)。

单个大dbcontext的一个问题是加载和初始化时间,因为它将映射所有实体,并且当您的实体数量在您的上下文中增加时,这会增加。

现在你的项目必须由模块组成,你可以将你的大dbcontext分成小的db上下文,涵盖每个单独模块需要使用数据库的所有内容,例如假设你的项目有两个模块(成员资格和对于客户/个人实体,您会发现当您在会员模块中与人交往时,您需要他的所有详细信息,但不是他的发票的完整详细信息,当您在计费模块中与此人交谈时,您将需要他的所有发票都是deatils而不是他的完整个人信息,在这里你可以为每个模块创建一个2个dbcontexts,其中person实体包含该模块从person实体需要的内容。

Julie lerman有一篇关于dbcontext和Entity-framework的文章很好,首先要了解我在这里要描述的内容的更多细节, https://msdn.microsoft.com/en-us/magazine/jj883952.aspx

希望这有帮助