Как управлять соединением в длительно существующем контексте объекта (платформа Entity Framework)

В данном разделе показано на примере, как вручную открыть соединение для длительно существующего контекста объекта. В примере также показано, как сделать, чтобы соединение гарантированно закрывалось при вызове метода Dispose для данного контекста.

Пример в этом разделе основан на модели Модель AdventureWorks Sales. Чтобы запустить код из данного примера, нужно сначала добавить к проекту модель AdventureWorks Sales и настроить его для использования платформы Entity Framework. Для этого выполните процедуру из раздела Как использовать мастер моделей EDM (платформа Entity Framework).

Пример

В данном примере проводится открытие соединения вручную в длительно существующем контексте объекта ObjectContext, затем выполнение запроса и сохранение изменений. Соединение закрывается при удалении контекста объекта ObjectContext.

' Define the order ID for the order we want. 
Dim orderId As Integer = 43680

' Create a long-running context. 
Dim context As New AdventureWorksEntities()
Try
    If context.Connection.State <> ConnectionState.Open Then
        ' Explicitly open the connection. 
        context.Connection.Open()
    End If

    ' Execute a query to return an order. 
    Dim order As SalesOrderHeader = context.SalesOrderHeaders.Where("it.SalesOrderID = @orderId", _
                                        New ObjectParameter("orderId", orderId)).Execute(MergeOption.AppendOnly).First()

    ' Change the status of an existing order. 
    order.Status = 1

    ' You do not have to call the Load method to load the details for the order, 
    ' because lazy loading is set to true 
    ' by the constructor of the AdventureWorksEntities object. 
    ' With lazy loading set to true the related objects are loaded when 
    ' you access the navigation property. In this case SalesOrderDetails. 

    ' Delete the first item in the order. 
    context.DeleteObject(order.SalesOrderDetails.First())

    ' Save changes. 
    If 0 < context.SaveChanges() Then
        Console.WriteLine("Changes saved.")
    End If

    ' Create a new SalesOrderDetail object. 
    ' You can use the static CreateObjectName method (the Entity Framework 
    ' adds this method to the generated entity types) instead of the new operator: 
    ' SalesOrderDetail.CreateSalesOrderDetail(1, 0, 2, 750, 1, (decimal)2171.2942, 0, 0, 
    ' Guid.NewGuid(), DateTime.Today)); 
    Dim detail = New SalesOrderDetail With
    {
        .SalesOrderID = 0,
        .SalesOrderDetailID = 0,
        .OrderQty = 2,
        .ProductID = 750,
        .SpecialOfferID = 1,
        .UnitPrice = CDec(2171.2942),
        .UnitPriceDiscount = 0,
        .LineTotal = 0,
        .rowguid = Guid.NewGuid(),
        .ModifiedDate = DateTime.Now
    }

    order.SalesOrderDetails.Add(detail)


    ' Save changes again. 
    If 0 < context.SaveChanges() Then
        Console.WriteLine("Changes saved.")
    End If
Catch ex As InvalidOperationException
    Console.WriteLine(ex.ToString())
Finally
    ' Explicitly dispose of the context, 
    ' which closes the connection. 
    context.Dispose()
// Define the order ID for the order we want.
int orderId = 43680;

// Create a long-running context.
AdventureWorksEntities context =
    new AdventureWorksEntities();

try
{
    if (context.Connection.State != ConnectionState.Open)
    {
        // Explicitly open the connection.
        context.Connection.Open();
    }

    // Execute a query to return an order.
    SalesOrderHeader order =
        context.SalesOrderHeaders.Where(
        "it.SalesOrderID = @orderId", new ObjectParameter("orderId", orderId))
        .Execute(MergeOption.AppendOnly).First();

    // Change the status of an existing order.
    order.Status = 1;

    // You do not have to call the Load method to load the details for the order,
    // because  lazy loading is set to true 
    // by the constructor of the AdventureWorksEntities object. 
    // With  lazy loading set to true the related objects are loaded when
    // you access the navigation property. In this case SalesOrderDetails.

    // Delete the first item in the order.
    context.DeleteObject(order.SalesOrderDetails.First());

    // Save changes.
    if (0 < context.SaveChanges())
    {
        Console.WriteLine("Changes saved.");
    }

    // Create a new SalesOrderDetail object.
    // You can use the static CreateObjectName method (the Entity Framework
    // adds this method to the generated entity types) instead of the new operator:
    // SalesOrderDetail.CreateSalesOrderDetail(1, 0, 2, 750, 1, (decimal)2171.2942, 0, 0,
    //                                         Guid.NewGuid(), DateTime.Today));
    SalesOrderDetail detail = new SalesOrderDetail
    {
        SalesOrderID = 0,
        SalesOrderDetailID = 0,
        OrderQty = 2,
        ProductID = 750,
        SpecialOfferID = 1,
        UnitPrice = (decimal)2171.2942,
        UnitPriceDiscount = 0,
        LineTotal = 0,
        rowguid = Guid.NewGuid(),
        ModifiedDate = DateTime.Now
    };

    order.SalesOrderDetails.Add(detail);


    // Save changes again.
    if (0 < context.SaveChanges())
    {
        Console.WriteLine("Changes saved.");
    }
}
catch (InvalidOperationException ex)
{
    Console.WriteLine(ex.ToString());
}
finally
{
    // Explicitly dispose of the context, 
    // which closes the connection. 
    context.Dispose();
}

См. также

Задачи

Как открыть соединения вручную из контекста объекта (платформа Entity Framework)

Основные понятия

Управление соединениями и транзакциями (платформа Entity Framework)