管理连接和事务(实体框架)

默认情况下,实体框架 管理到数据库的连接。 不过,您可以在实体框架 应用程序中手动管理连接和事务。

连接和实体框架

实体框架 仅在需要时(例如执行查询或调用 SaveChanges)才打开连接,随后在操作完成后关闭连接。

调用以下任一方法都会打开连接:

Bb896325.note(zh-cn,VS.100).gif注意:
调用查询方法时,连接将打开,并且一直保持打开状态,直到 ObjectResult 已被完全消耗或处置为止。

手动管理连接

实体框架 通过 Connection 属性公开 EntityConnection。 这使您能够管理连接和事务处理或提供您自己的 EntityConnection。 当您想要在短暂的对象上下文中使连接保持打开状态以便提高性能或显式控制事务处理时,这是有用的。 实体框架 使用的同一提供程序连接可以与应用程序的其他部分共享。 下面的示例说明如何显式打开连接:

' Explicitly open the connection. 
context.Connection.Open()
// Explicitly open the connection.    
context.Connection.Open();

有关更多信息,请参见如何:手动从对象上下文打开连接(实体框架)

当您在长时间运行的对象上下文中手动打开连接时,必须调用 Dispose 方法以确保在不再需要该上下文时关闭连接。 您还可以对 EntityConnection 调用 Close 方法以显式关闭该连接。 有关更多信息,请参见如何:在长时间运行的对象上下文中管理连接(实体框架)

您还可以创建一个 EntityConnection 并将此连接提供给对象上下文。 在这种情况下,您可以手动打开连接,或者让对象上下文在需要时打开它。 在向对象上下文提供 EntityConnection 之后,您必须确保上下文和 EntityConnection 都在其不再需要时得到处置。 下面的示例创建一个连接并将其传递给对象上下文:

' Create an EntityConnection. 
Dim conn As New EntityConnection("name=AdventureWorksEntities")

' Create a long-running context with the connection. 
Dim context As New AdventureWorksEntities(conn)
// Create an EntityConnection.
EntityConnection conn =
    new EntityConnection("name=AdventureWorksEntities");

// Create a long-running context with the connection.
AdventureWorksEntities context =
    new AdventureWorksEntities(conn);

有关更多信息,请参见如何:将 EntityConnection 用于对象上下文(实体框架)

管理连接的注意事项

在管理连接时,需要考虑以下注意事项:

  • 如果连接在操作之前尚未打开,则对象上下文将打开该连接。 如果对象上下文在操作过程中打开连接,它总是在操作完成后关闭该连接。

  • 如果您手动打开连接,对象上下文将不会关闭它。 调用 CloseDispose 将关闭连接。

  • 如果对象上下文创建了连接,该连接总是在上下文被处置时进行处置。

  • 在长期运行的对象上下文中,必须确保该上下文在不再需要时被处置。

如果您为对象上下文提供一个打开的 EntityConnection,则必须确保对该上下文进行了处置。

事务和实体框架

实体框架 支持自动事务登记。 这意味着通过在 System.Transactions 事务中执行操作,可以将在对象上下文中执行的活动(如在数据源中执行查询和保存对数据的更改)隔离在数据源中。 事务用于在实体框架 中执行以下操作:

  • 对必须完全一致的数据源执行多个操作,如取决于是否成功完成对象更改的查询。

  • 与其他分布式操作(例如发送电子邮件通知或写入消息队列)协调对象上下文中的更改。

要求登记附加资源管理器的事务称为“分布式事务”**。 分布式事务使用一个分布式事务处理协调器 (DTC) 来管理完成事务所需的资源。 建立和完成事务向 DTC 的提升是一个相对耗费资源的过程。 一些资源管理器(例如 SQL Server 2005)支持可提升的单阶段登记 (PSPE) 事务协议。 这允许资源管理器承载可在以后必要时升级为由分布式事务协调器 (DTC) 来管理的事务。

有关 System.Transactions 的更多信息,请参见Transaction Processing。 有关在 SQL Server 中使用 System.Transactions 的更多信息,请参见System.Transactions Integration with SQL Server (ADO.NET)

管理事务的注意事项

当您在实体框架 中使用事务时,需要考虑以下注意事项:

  • 仅对针对数据源的操作进行事务处理。 对对象上下文中对象的更改不进行事务处理。 在上下文中对对象的更改在事务范围以外可见。

  • 当您调用 SaveChanges 时,如果存在一个当前事务,则实体框架 会将此事务用于针对数据源的操作。 否则,将为操作创建新事务。 可以使用 EntityTransactionTransactionTransactionScope 来定义事务。

    Bb896325.note(zh-cn,VS.100).gif注意:
    若要在现有事务中登记,实体框架 可能会先关闭连接然后重新打开。

  • 当实体框架 为 SaveChanges 操作创建新事务时,在该事务完成之前,不接受对对象上下文中的对象所做的更改。 这样可以确保对象上下文的状态与数据源一致。

  • 当在单个事务中关闭连接并重新打开时,事务可能会提升到 DTC。 由于实体框架 会自动打开和关闭连接,因此您应该考虑手动打开和关闭连接以避免发生事务提升。 有关更多信息,请参见如何:手动从对象上下文打开连接(实体框架)

  • 如果您计划在事务中重试操作,则必须要确保在事务完成之前,对象上下文中对象的状态没有重置。 为此,必须调用 acceptChangesDuringSave 参数值为 falseSaveChanges,然后仅当事务中其他操作已成功完成后再调用 AcceptAllChanges。 有关更多信息,请参见如何:在实体框架中管理事务

作为使用协调的事务进行重试操作的一部分,可以再次调用 SaveChanges 而无需先调用 AcceptAllChanges。 在这种情况下,实体框架 会尝试对数据源重新应用同样的更改。

本节内容

如何:手动从对象上下文打开连接(实体框架)

如何:在长时间运行的对象上下文中管理连接(实体框架)

如何:将 EntityConnection 用于对象上下文(实体框架)

如何:在实体框架中管理事务