EF中的连接模型和断开模型

15

我对实体框架中的连接模型和断开模型感到困惑。

以前我使用传统的ADO.net,当需要多个用户同时进行更新或插入时使用连接模型(使用DataReader);而在少数情况下,需要将数据发送到其他进程,在内存中对数据进行某些操作,然后再将其发送回数据库时,则使用断开模型(使用DataAdapter)。

现在我读了一些关于实体框架中连接模型和断开模型的文章,我不明白为什么在断开模型中要显式地将实体附加到上下文中?我还读到,Web应用程序的默认行为是使用断开模型,而WPF则使用连接模型!


  • 能否用类比真实生活的方式简单易懂地解释这两种模型之间的区别?
  • 我们如何使用实例来处理EF中的这两种模型?
  • 应用程序类型(Web表单、MVC、WPF、WCF)和EF中使用的专用模型之间是否有关系?
  • 何时应该使用连接模式,何时应该使用断开模式(使用EF)?
回答:
- 连接模型是像打电话一样,你必须一直保持联系才可以互相交流,而断开模型就像写信一样,你可以先写下你想说的话然后发送出去,接收者可以在合适的时间回复你。 - 我们可以使用实体框架(EF)来处理这两种模型。对于连接模型,我们可以直接通过上下文进行查询和更新。对于断开模型,我们需要将数据加载到本地内存中进行操作,然后再将更改保存回数据库。 - 不一定。应用程序类型并不决定我们应该使用哪种模型。实际上,我们可以根据具体情况来选择使用哪种模型。 - 当需要经常进行数据修改和操作时,可以考虑使用连接模型;而当需要在本地内存中进行大量计算和操作时,则应该使用断开模型。

这个网站有几个关于“断开连接”的参考资料,我觉得很有帮助。http://www.entityframeworktutorial.net/update-one-to-many-entities-in-entity-framework.aspx 或者这里是一个“钓东西”的链接:https://www.google.com/?gws_rd=ssl#q=disconnected+site:http:%2F%2Fwww.entityframeworktutorial.net%2F - granadaCoder
2个回答

11

背景

ADO.NET Framework支持两种数据访问架构模型:

  1. 连接导向
  2. 断开式

在连接导向的数据访问架构中,应用程序与数据源建立连接,并通过 SQL 请求与其进行交互,使用相同的连接(例如,即使不使用任何数据库操作,也必须维护应用程序和数据源之间的打开连接)。

连接式架构是指您不断地对数据库进行任何CRUD(创建、读取、更新和删除)操作。这会增加到数据库的流量,但通常更快,因为您应该执行较小的事务。

它是基于类 Connection, Command, DataReaderTransaction 构建的。

enter image description here

在断开式数据访问架构中,ADO.net使用内存数据存储器,可以同时保存多个表格(它们在先前被提取)。
断开式架构是一种从数据库检索记录集并将其存储的方法,使您能够在内存中执行许多CRUD(创建、读取、更新和删除)操作,然后在重新连接时可以重新与数据库同步。
它建立在类Connection、DataAdapter、CommandBuilder、DataSet和DataView之上。

enter image description here


连接和断开架构的一些关键类

  • DataReader连接架构,因为它保持连接打开直到逐行获取所有行。
  • DataSet断开架构,因为所有记录都一次性带出,不需要保持连接活动。
  • DataAdapter 充当连接和断开对象之间的桥梁。它通过将数据从数据源填充到Dataset来管理数据源和Dataset之间的连接。

在所需情况下哪个更好?

连接模式

  • 面向连接
  • 我们使用DataReader对象从数据库中读取数据
  • 其方法提供更快的性能
  • 它可以保存单个表的数据
  • 它是只读的,我们不能更新数据

断开模式

  • 它是断开连接的面向连接。
  • 我们使用 DataSet 对象从数据库中读取数据。
  • 速度和性能都较低。
  • 它可以容纳多个数据表。
  • 我们可以执行所有选项,如更新、插入、删除等操作。

你的问题的答案

我现在读了一些关于EF中连接模型和断开模型的文章,我很困惑为什么在断开模型中需要显式地将实体附加到上下文中?我也读到过在Web中默认行为是断开模型,在WPF中是连接模型!

Web应用程序可以是连接或断开的,事实上,由于ADO.NET断开模型,ASP.NET应用程序实际上是断开的。由于其简单的实现和更容易的故障排除,断开模型越来越受欢迎。在ASP.NET应用程序中,良好的设计应该在数据操作完成后立即关闭所有数据库连接,无论每月有15次点击还是每秒钟有15次点击。

有人能用生活的类比以简单的方式解释两种模型之间的区别吗?

可以的,假设你有一些重要的提示要告诉/让朋友意识到。 断开模型表示你等待看到他或花时间获取更多提示以便说出来。 连接模型是当你与他一起生活或在线/实时与他进行通信,每次想要告诉他每个提示的方式。

我希望您能用简单的例子来处理EF中的两个模型?
EF使用“断开连接”的模型。因为您使用数据并进行所需的更改,然后执行SaveChanges:)
应用程序类型(Web表单、MVC、WPF、WCF)和EF中使用的专用模型之间是否存在关系?
这基于应用程序逻辑。实时应用程序需要连接,因为它们需要实时传播和更新,而不是其他应用程序类型。
何时使用连接模型,何时使用断开连接模型(使用EF)?
我已回答过这个问题。只是想说,通过仅在最短时间内保持连接,ADO.NET可以节省系统资源,并为数据库提供最大安全性,并且对系统性能的影响较小。它基于您的应用程序策略/类型,您可以自己做出好的决定。
如果我处于断开连接的模式下,您能告诉我EF如何同时处理多个用户的多个操作(插入,更新,删除)吗?
请看ObjectStateManager,它负责上下文中与对象跟踪相关的一切。如果一些用户对同一条目执行并发更新,默认情况下,Entity Framework 实现了乐观并发模型。这意味着在从数据源查询数据到更新数据之间,不会锁定数据源中的数据。Entity Framework 会保存对象更改到数据库而不检查并发。 对于可能经历高度并发的实体(如银行系统),我们建议实体在概念层中定义一个带有 ConcurrencyMode="fixed" 属性的属性,如以下示例所示:
<Property Name="Status" Type="Byte" Nullable="false" ConcurrencyMode="Fixed" />

当使用此属性时,实体框架在将更改保存到数据库之前会检查数据库中的更改。任何冲突的更改都会导致 OptimisticConcurrencyException,这也可能发生在定义使用存储过程更新数据源的实体数据模型时。在这种情况下,当用于执行更新的存储过程报告未更新任何行时,将引发异常。有关更多信息,请访问 保存更改和管理并发性

@just_name 很好的问题 :) 我会尽快在我的帖子末尾放上你的答案。 - Amirhossein Mehrvarzi
@just_name,我终于回答了你上次的问题。 - Amirhossein Mehrvarzi
1
默认情况下,Entity Framework 实现了一种乐观并发模型。不,它默认没有实现任何并发模型。应用“ConcurrencyMode = fixed”被称为乐观并发,但对于具有分布式事务的系统来说,这太简单了。 - Gert Arnold
@GertArnold 发生了什么?! 我说的有错吗(基于EF参考文献)?还是你意思是别的? - Amirhossein Mehrvarzi
这真的很令人困惑!乐观并发的常见定义总是提到类似于“在提交之前,每个事务都会验证没有其他事务修改了它所读取的数据。”(维基百科)。这就是为什么在EF中实现此模型时会抛出OptimisticConcurrencyException异常。 - Gert Arnold
显示剩余2条评论

10

ADO.Net

"'Connected'和'disconnected'在ADO.Net中涉及数据库连接。DataReader始终具有打开的连接,DataSet/DataAdapter在必要时连接到数据库。在ADO.Net术语中,Entity Framework始终以断开模式运行。每个EF的数据库操作都会打开和关闭数据库连接(除非您明确覆盖此行为)。这是唯一重要的事情。不需要扩展(断)连接的ADO.Net的详细信息。通常不建议长时间保持数据库连接处于打开状态。

软件架构

在软件架构中,“connected”和“disconnected”通常指1层与N层。在1层应用程序中,例如WPF应用程序,用户界面和数据访问层(DAL)运行在同一个应用程序进程中。UI与DAL相连。并不是它将始终具有到数据库的打开连接,但数据库始终可用。由DAL从数据存储库获取的对象可以在UI中处理,并且相同的对象可以返回到DAL并保存到数据存储库(使用新的数据库连接)。

"
在N-tier应用程序中,UI界面和数据访问层通过网络连接分离,也就是"断开"。假设数据访问层是Web服务的一部分。Web服务通常是无状态的:它生成响应并忘记它们。此外,对象将在连接的两端进行序列化和反序列化。当响应进入网络时,对象消失了。

Entity Framework

正如你现在怀疑的那样,在EF世界中,“断开”指的是后者,即N-tier应用程序。
在1-tier应用程序中,您可以选择拥有一个上下文(一个DbContext),该上下文生成实体,并在UI中进行任何修改时保存相同的实体。不需要将它们重新附加到新的上下文中。(是否明智保持这种方式的上下文是另一个问题)。
在N-tier应用程序中,上下文要么生成实体,要么保存实体,而不能同时进行。它生成实体,这些实体被序列化,然后上下文被处理。从客户端应用程序返回的实体进行反序列化,然后重新附加到保存其更改的新上下文实例。这是你困惑的源头...

为什么在断开模式下我需要显式将实体附加到上下文中

如果你从架构角度来看,“断开连接”就会有意义。在Entity Framework文档中,有一个完整章节讲解此主题
因此,你的问题

何时使用连接模型和何时使用断开连接模型(使用EF)

可以回答如下:
  • 从ADO.Net的角度来看,没有选择(除了一些特殊情况),EF是以断开连接的方式工作的(即:不保持连接打开状态)。
  • 从架构角度来看,当应用程序是N层时,就不存在选择:它总是断开连接的(即:分离并重新附加,实体不是通过同一上下文创建并且保存)。
    只有在1层应用程序中,才可以选择连接方案。在这种情况下,应该仔细管理上下文生命周期。当上下文包含“许多”对象时,上下文会变得缓慢且消耗内存。当上下文具有较长的生命周期时,很难使任何应用程序保持灵敏。在我看来,即使在1层应用程序中,也应该优先考虑断开连接的场景。

但是,如果我处于无法选择的断开模式中,正如您所说的那样!您能告诉我EF如何处理多个用户同时进行的多个操作(INSERTsUPDATEsDELETEs)吗?如果我开发一个银行系统或购买模块,EF断开模式如何处理? - Anyname Donotcare
1
这是一个非常广泛的问题。通常,在多用户环境中使用乐观并发策略,但对于银行系统来说,这显然是不够的,你需要锁定策略和分布式事务。但这太复杂了,在一篇回答中描述不清楚(并且对于我来说,老实说,在彻底研究它之前也不行)。 - Gert Arnold
我的意思是,“并发策略”与模型(“连接的、断开的”)有关吗?! - Anyname Donotcare
1
实际上这两者没有关系。是否应用并发策略以及选择哪种策略,并不取决于应用程序模型。当使用分离实体时,实现方式与单层应用程序不同,但这又是另一个话题了,与此无关。 - Gert Arnold

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接