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

Posted

技术标签:

【中文标题】EF中的连接模型和断开模型【英文标题】:connected model and disconnected model in EF 【发布时间】:2015-10-24 04:05:07 【问题描述】:

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

我使用的是传统的 ADO.net(DataReader 用于连接模型,DataAdapter 用于断开模型) 我所知道的,当我有许多用户需要一起更新或插入时,我使用连接模型,而在一些情况下,当我需要将数据发送到其他进程时,我使用断开模型对内存中的数据进行一些操作并将它们发送回来到数据库。

现在我在 EF 中阅读了一些关于连接模型和断开模型的文章,我很困惑为什么我应该将实体显式附加到断开模型的上下文中? 我还读到 web 中的默认行为是断开连接的模型,而 WPF 中的默认行为是连接的模型!


谁能用现实生活的类比简单地解释一下 这两种型号有什么区别? 我们如何通过简单的示例在 EF 中处理这两种模型? app 类型(web 表单)之间是否有关系 、MVC、WPF、WCF)和EF中使用的专用模型? 何时使用连接模型以及何时使用断开模型(使用 EF)?

【问题讨论】:

这个网站有几个对“断开连接”的引用,我发现它们很有帮助。 entityframeworktutorial.net/… 或者这里是“钓鱼”链接:google.com/… 【参考方案1】:

背景

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

    面向连接 断开连接

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

连接架构是指您不断访问数据库以执行您希望执行的任何 CRUD(创建、读取、更新和删除)操作。这会为数据库创建更多流量,但通常会更快,因为您应该执行较小的事务。

它建立在 ConnectionCommandDataReaderTransaction 类之上。

在断开连接的数据访问架构中,ADO.net 使用内存中的数据存储,该存储可以同时保存多个表(之前已获取)。

断开式架构是一种从数据库中检索记录集并将其存储的方法,使您能够对内存中的数据执行许多 CRUD(创建、读取、更新和删除)操作,然后可以重新同步重新连接时使用数据库。

它基于类 ConnectionDataAdapterCommandBuilderDataSetDataView


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

DataReader互联架构,因为它保持 连接打开,直到所有行都被一一获取。 DataSetDisconnected Architecture,因为所有记录都是 立即带来,无需保持连接。 DataAdapter 充当 Connected 和 断开的对象。它管理数据源和数据源之间的连接 Dataset 将数据源中的数据填充到Dataset

在理想情况下哪一个更好?

连接模式

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

断开模式

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

回答您的问题

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

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

有人可以用现实生活的类比简单地解释一下吗 两种型号有什么区别?

是的,假设您有一些重要的提示要告诉/了解朋友。 断开连接表示您一直在等待见到他,或者您正在花时间获取更多提示。 连接是您与他一起生活或与他进行在线/实时通信的方式,以便您每次都告诉他每一个提示。

我们如何通过简单的示例在 EF 中处理这两种模型?

EF 使用 断开连接 模型。因为您使用数据并进行所需的更改,然后执行SaveChanges :)

app的类型(web form、MVC、WPF、 WCF) 和 EF 中使用的专用模型?

它基于应用程序逻辑。需要连接实时应用程序,因为它们需要按时传播和更新,而不是其他应用程序类型。

何时使用连接模型以及何时使用断开模型(使用 英法)?

我已经回答过了。只是我想说通过仅在最短的时间内保持连接打开,ADO.NET 可以节省系统资源并为数据库提供最大的安全性,并且对系统性能的影响也较小。这取决于您的应用策略/类型,您可以自己做出正确的决定。

更新

但是如果我处于断开连接的模型中,你能告诉我 EF 是如何做到的吗? 处理来自多个用户的多个操作(插入、更新、删除) 同时?

看看ObjectStateManager,它负责与上下文中的对象跟踪相关的所有事情。 如果某些用户对同一个条目进行并发更新,默认情况下,Entity Framework 实现了一个乐观并发模型。这意味着在查询数据和更新数据之间,不会对数据源中的数据进行锁定。 实体框架将对象更改保存到数据库而不检查并发性。对于可能经历高度并发性的实体(如银行系统),我们建议实体在概念层定义一个属性ConcurrencyMode="fixed"的一个属性,如下例所示:

<Property Name="Status" Type="Byte" Nullable="false" ConcurrencyMode="Fixed" />

使用此属性时,实体框架会在将更改保存到数据库之前检查数据库中的更改。任何有冲突的更改都会导致OptimisticConcurrencyException,当您定义使用存储过程对数据源进行更新的实体数据模型时,也会发生这种情况。在这种情况下,当用于执行更新的存储过程报告零行已更新时,将引发异常。欲了解更多信息,请访问Saving Changes and Managing Concurrency

【讨论】:

但是如果我处于断开连接的模型中,您能告诉我EF 如何同时处理来自多个用户的多个操作(插入、更新、删除) @just_name 好问题 :) 我会尽快将您的答案放在帖子的最后。 @just_name 我终于把你最后一个问题的答案放上来了 默认情况下,Entity Framework 实现一个乐观并发模型。不,默认情况下它不实现任何并发模型。应用ConcurrencyMode="fixed" 被称为乐观并发,但这对于具有分布式事务的系统来说是一种简单的方式。 @GertArnold 那么发生了什么?!我说的有错吗(基于 EF 参考)?或者,你还有别的意思吗?【参考方案2】:

ADO.Net

ADO.Net 中的“已连接”和“已断开连接”是关于数据库连接DataReader 总是有一个打开的连接,DataSet/DataAdapter duo 在必要时连接到数据库。

我认为一个常见的现实类比是打电话。如果你想让朋友在你开车的时候告诉你去他家的路,你会更喜欢“连接模式”:在通话过程中,你来回交谈,直到你到达那里。为每条指令开始一个新的电话呼叫太耗时了。 但是如果你问住在两个街区外的妈妈,看看你是否关上了厨房的窗户,你会打电话给她,她会去检查并给你回电话:“断开连接”。与此同时,你将继续做你正在做的事情。

从这个意义上说,Entity Framework 始终在断开连接模式下运行。 EF 的每个数据库操作都会打开和关闭数据库连接(除非您明确覆盖此行为)。

软件架构

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

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

实体框架

正如您现在所怀疑的那样,在 EF 世界中,“断开连接”指的是后一种含义,即 N 层应用程序。

在 1 层应用程序中,您可以选择在 UI 中进行任何修改时生成实体并保存相同实体的上下文(DbContext)。无需将它们重新附加到新的上下文中。 (将上下文保持这么长时间是否明智是一个不同的问题)。

在 N 层应用程序中,上下文要么生成实体保存实体,而不是两者。它生成被序列化的实体并处理上下文。从客户端应用程序返回的实体被反序列化并重新附加到保存其更改的新上下文实例。这是你困惑的根源......

为什么要在断开连接的模型中将实体显式附加到上下文中

如果您在架构内涵中阅读“断开连接”,这一切都是有道理的。 Lerman 和 Miller 在他们的书 Programming Entity Framework: DbContext 第 4 章:处理包括 N 层应用程序在内的断开连接的实体 中描述了整个过程。

现在你的问题

何时使用连接模型,何时使用非连接模型(使用 EF)

可以这样回答:

从 ADO.Net 的角度来看,没有选择(除了一些特殊情况),EF 在断开连接的情况下工作(例如:不保持连接打开)。 从架构的角度来看,当应用程序是 N 层时,别无选择:它总是断开连接(例如:分离并重新连接,实体不会创建通过相同的上下文)。 只有在 1 层应用程序中才有选择。这一选择将我们带到了上下文生命周期管理领域。关于这一点已经说了很多。一个不可否认的事实是,当上下文包含“许多”对象时,它会变得很慢并且会消耗内存。当上下文的生命周期很长时,很难让任何应用程序保持快速,因此即使在数据量大的 1 层应用程序中,也应该认真考虑断开连接(分离)的情况。

【讨论】:

但是如果我处于断开连接的模型中而没有您所说的选择!,您能告诉我EF 如何同时处理来自多个用户的多个操作(INSERTs,UPDATEs,DELETEs) 吗?如果我开发一个银行系统或采购模块,EF 断开模型如何处理呢? 您在这里提出的问题非常广泛。通常乐观并发策略用于多用户环境,但对于银行系统来说这还不够,显然,您需要锁定策略和分布式事务。但这太复杂了,无法用一个答案来描述(坦率地说,对我来说,没有先彻底研究它)。 我的意思是concurrency strategies与模型相关(connected,disconnected)?! 其实没有关系。是否应用并发策略以及使用哪种策略的问题不取决于应用程序模型。使用分离实体时的实现将不同于在 1 层应用程序中的实现,但同样,这是题外话。

以上是关于EF中的连接模型和断开模型的主要内容,如果未能解决你的问题,请参考以下文章

深度学习-ssh远程连接断开之后怎样让模型继续训练

Colab Pro 在使用 TPU 运行时训练深度学习模型 12 小时后自动断开连接

尝试使用 Keras 功能 API 构建 CNN 模型时图形断开连接

EF6+MySql 软件配置环境 EF连接不到mysql问题 实体数据模型向导 选不到mysql

多输出自定义keras ResNet50模型; ValueError:图表已断开连接

OSI参考模型