2011-07-19 8 views
12

Próbuję ponownie użyć istniejącego połączenia z bazą danych, aby móc wykonywać wiele operacji na bazach danych przy użyciu TransactionScope bez wywoływania usługi MSDTC.DbContext nie pozostawi połączenia otwartego do ponownego użycia

Entity Framework (przy użyciu nowego interfejsu API DbContext w wydaniu 4.1) nie chce, aby otwarcie jawnie otwartego połączenia było otwarte. Stary interfejs API ObjectContext utrzymuje połączenie otwarte zgodnie z oczekiwaniami i documented.

Od DbContext API po prostu używa ObjectContext pod maską, oczekiwałbym tego samego zachowania. Czy ktoś wie, czy ta zmiana jest zamierzona, czy znany problem? Nie mogę znaleźć nigdzie udokumentowanej dokumentacji.

public void ConnectionRemainsOpen() 
{ 
    using (var context = new TestDataContext()) 
    { 
     try 
     { 
      Assert.AreEqual(ConnectionState.Closed, context.Database.Connection.State); 

      context.Database.Connection.Open(); 

      var firstRecord = context.Table3.FirstOrDefault(); 

      // this Assert fails as State == ConnectionState.Closed 
      Assert.AreEqual(ConnectionState.Open, context.Database.Connection.State); 

      var newRecord = new Table3 
      { 
       Name = "test", 
       CreatedTime = DateTime.UtcNow, 
       ModifiedTime = DateTime.UtcNow 
      }; 

      context.Table3.Add(newRecord); 

      context.SaveChanges(); 

      // this Assert would also fail 
      Assert.AreEqual(ConnectionState.Open, context.Database.Connection.State); 
     } 
     finally 
     { 
      if (context.Database.Connection.State == ConnectionState.Open) 
       context.Database.Connection.Close(); 
     } 
    } 
} 
+0

Jeśli umieścisz Asert po Open(), ale przed pierwszym zapytaniem, jaki jest wynik? Zastanawiam się, czy problem polega właśnie na tym, że zwraca on nieprawidłową wartość, a nie na zamykaniu i ponownym otwieraniu połączeń. – Tridus

+0

@Tridus, sugerowane przez Ciebie Asert zawiera oczekiwany wynik 'Open'. – GWB

+0

Zdaję sobie sprawę, że jest to stary wpis, ale właśnie czytałem książkę Julii Lerman, a używana przez nią składnia to context.Connection.Open() (tzn. Brak bazy danych między kontekstem a połączeniem). Tylko myśl. – Tod

Odpowiedz

14

Jeśli chcesz kontrolować połączenia należy go utworzyć przed kontekstu i przekazać je do kontekstu w przeciwnym razie połączenie nie jest pod kontrolą. Spróbuj coś takiego:

using (var connection = ...) 
{ 
    using (var context = new TestDataContext(connection, false)) 
    { 
     ... 
    } 
} 
+0

Czy jest to udokumentowana zmiana między EF 4.0 a 4.1? – GWB

+0

Myślę, że jest to udokumentowane, ponieważ drugi parametr konstruktora mówi, czy kontekst jest właścicielem połączenia. –

+0

Próbowałem Twojego rozwiązania, ale otrzymałem taki sam wynik. Kontekst nadal zmienia stan połączenia zgodnie z oczekiwaniami. – GWB

Powiązane problemy