📜  Entity Framework-生命周期

📅  最后修改于: 2020-11-21 07:16:35             🧑  作者: Mango


一生

上下文的生命周期从创建实例开始,到实例被处置或垃圾回收时结束。

  • 使用ORM时,上下文生存期是一个非常关键的决定。

  • 上下文的执行就像实体缓存一样,因此意味着它持有对所有已加载实体的引用,这些引用的内存使用量可能会快速增长,并且还可能导致内存泄漏。

  • 在下图中,您可以通过Context查看从应用程序到数据库的数据工作流程的上层,反之亦然。

数据工作流程

实体生命周期

实体生命周期描述了创建,添加,修改,删除实体等的过程。实体在其生命周期中具有许多状态。在研究如何检索实体状态之前,让我们看一下什么是实体状态。状态是类型为System.Data.EntityState的枚举,它声明以下值-

  • 已添加:实体被标记为已添加。

  • 已删除:实体被标记为已删除。

  • 已修改:实体已被修改。

  • 不变:实体尚未修改。

  • 已分离:未跟踪实体。

实体生命周期中的状态更改

有时,实体的状态由上下文自动设置,但开发人员也可以手动修改。即使从一种状态到另一种状态的所有开关组合都是可能的,但是其中一些是没有意义的。例如,将“添加的实体”设置为“已删除”状态,反之亦然。

让我们讨论不同的状态。

不变的状态

  • 当实体不变时,它绑定到上下文,但尚未修改。

  • 默认情况下,从数据库检索到的实体处于此状态。

  • 当实体(使用Attach方法)附加到上下文时,它类似地处于Unchanged状态。

  • 上下文无法跟踪未引用的对象的更改,因此在附加上下文时,假定它们是未更改的。

分离状态

  • 分离是新创建的实体的默认状态,因为上下文无法跟踪代码中任何对象的创建。

  • 即使您在上下文的using块内实例化实体,也是如此。

  • 禁用跟踪时,甚至是从数据库中检索到的实体的状态。

  • 分离实体时,它没有绑定到上下文,因此不会跟踪其状态。

  • 可以将其丢弃,修改,与其他类组合使用或以您可能需要的任何其他方式使用。

  • 因为没有上下文对其进行跟踪,所以它对实体框架没有任何意义。

新增状态

  • 当实体处于“已添加”状态时,几乎没有选择。实际上,您只能将其与上下文分离。

  • 自然,即使您修改了某些属性,该状态仍保持为已添加,因为将其移至“已修改”,“未更改”或“已删除”是没有意义的。

  • 这是一个新实体,与数据库中的一行没有对应关系。

  • 这是处于其中一种状态的基本前提(但此规则不受上下文强制)。

新增状态

修改状态

  • 修改实体时,这意味着它处于“未更改”状态,然后更改了某些属性。

  • 实体进入“修改”状态后,它可以移动到“已分离”或“已删除”状态,但是即使您手动还原原始值,也无法回滚到“未更改”状态。

  • 除非您将实体分离并将其添加到上下文中,否则它甚至不能更改为“已添加”,因为具有该ID的行已经存在于数据库中,并且在持久存储该异常时会遇到运行时异常。

删除状态

  • 实体由于未更改或已修改而进入Deleted状态,然后使用DeleteObject方法。

  • 这是限制性最强的状态,因为从该状态更改为除“分离”之外的任何其他值都没有意义。

如果希望将上下文控制的所有资源都放置在块的末尾,则使用using语句。当使用using语句时,编译器会自动创建一个try / finally块,并在finally块中调用dispose。

using (var context = new UniContext()) {

   var student = new Student {
      LastName = "Khan", 
      FirstMidName = "Ali", 
      EnrollmentDate = DateTime.Parse("2005-09-01")
   };

   context.Students.Add(student);
   context.SaveChanges();
}

使用长时间运行的上下文时,请考虑以下内容-

  • 当您将更多对象及其引用加载到内存中时,上下文的内存消耗可能会迅速增加。这可能会导致性能问题。

  • 请记住在不再需要上下文时将其丢弃。

  • 如果异常导致上下文处于不可恢复的状态,则整个应用程序可能会终止。

  • 随着查询和更新数据之间的时间间隔的增加,遇到与并发相关的问题的机会也会增加。

  • 使用Web应用程序时,每个请求都使用一个上下文实例。

  • 使用Windows Presentation Foundation(WPF)或Windows窗体时,请为每个窗体使用上下文实例。这使您可以使用上下文提供的变更跟踪功能。

经验法则

网络应用

  • 现在,对于Web应用程序来说,每个请求都使用上下文是一种常见的最佳实践。

  • 在Web应用程序中,我们处理非常短的请求,但保留了所有服务器事务,因此它们是上下文存在的适当持续时间。

桌面应用

  • 对于桌面应用程序,例如Win Forms / WPF等,按表单/对话框/页面使用上下文。

  • 由于我们不想将上下文作为应用程序的单例,因此当我们从一种形式转换为另一种形式时,将对其进行处理。

  • 这样,我们将获得很多上下文的能力,并且不会受到长期运行上下文的影响。