Mam nadzieję, że ktoś może mi pomóc w rozwiązaniu następującego problemu. Aplikacja, w której wystąpił błąd, jest uruchomiona podczas produkcji i sam nigdy nie doświadczyłem tego błędu. Jednak około 20 razy dziennie otrzymuję wiadomość o błędzie z informacją:Okazjonalne Błędy "Dostawca podstawowy nie powiodło się podczas otwierania" podczas korzystania z EF4 (model edmx)
Dostawca podstawowy nie spełnia warunków Open. ---> System.InvalidOperationException: połączenie nie zostało zamknięte. Bieżący stan połączenia łączy się.
Oto ślad stosu
System.Data.EntityException: Podstawowym dostawcą powiodło się na Open. ---> System.InvalidOperationException: połączenie nie zostało zamknięte. Aktualny stan połączenia to połączenie. w System.Data.ProviderBase.DbConnectionBusy.OpenConnection (DbConnection outerConnection, DbConnectionFactory ConnectionFactory) w System.Data.SqlClient.SqlConnection.Open() w HibernatingRhinos.Profiler.Appender.ProfiledDataAccess.ProfiledConnection.Open() w System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf (logiczna openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, logiczna & closeStoreConnectionOnFailure) --- Koniec wewnętrznej wyjątkiem stosu śladu --- w System.Data .EntityClient.EntityConnection.OpenStoreConnectionIf (Logiczna openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, logiczna & closeStoreConnectionOnFailure) w System.Data.EntityClient.EntityConnection.Open() w System.Data.Objects.ObjectContext.EnsureConnection(), w System.Data.Objects.ObjectQuery forMergeOption) w System.Data.Objects.ObjectQuery źródła) w System.Data.Objects.ELinq.ObjectQueryProvider.b__1 [TResult] (IEnumerable zapytania Wyrażenie queryRoot) pod adresem Sys tem.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute [S] (wyrażenie ekspresji) z System.Linq.Queryable.FirstOrDefault [TSource] (źródło IQueryable`1)
w GuideSites.DomainModel .Repositories.ClinicTermRepository.GetClinicTermByGuideSiteId (Int32 guideSiteId) w C: \ Projects \ GuideSites \ GuideSites.DomainModel \ Repositories \ ClinicTermRepository.cs: linia 20 przy GuideSites.Web.Frontend.Helpers.VerifyUrlHelper.RedirectOldUrls() w C: \ Projects \ GuideSites \ GuideSites.Web.Frontend \ Helpers \ VerifyUrlHelper.cs: line 91 at GuideSites.Web.Frontend.MvcApplication.Application_BeginRequest (Object nadawcy EventArgs e) C: \ Projects \ GuideSites \ GuideSites.Web.Frontend \ Global.asax.cs: Linia 412 w System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute () w System.Web.HttpApplication.ExecuteStep (IExecutionStep krok, Boolean & completedSynchronously)
używam EF4 pośrednictwem modelu EDMX i sposób połączyć się z bazą danych (MS SQL 2008) jest przez HttpContext opartej kontekście per żądanie obiektu tak, że połączenia z bazą danych nie są otwierane i zamykane dla każdego pojedynczego fragmentu danych potrzebnego na danym pageload.
Moja klasa kontekst bazy danych wygląda następująco:
public class DatabaseContext : IDisposable
{
private const string ContextName = "context";
private static dbEntities _dbEntities;
public dbEntities GetDatabaseContext()
{
SqlConnection.ClearAllPools();
if (HttpContext.Current == null)
return _dbEntities ?? (_dbEntities = new dbEntities());
if (HttpContext.Current.Items[ContextName] == null)
HttpContext.Current.Items[ContextName] = new dbEntities();
_dbEntities = (dbEntities)HttpContext.Current.Items[ContextName];
if (_dbEntities.Connection.State == ConnectionState.Closed)
{
_dbEntities.Connection.Open();
return _dbEntities;
}
return _dbEntities;
}
public void RemoveContext()
{
if (HttpContext.Current != null && HttpContext.Current.Items[ContextName] != null)
{
((dbEntities)HttpContext.Current.Items[ContextName]).Dispose();
HttpContext.Current.Items[ContextName] = null;
}
if (_dbEntities != null)
{
_dbEntities.Dispose();
_dbEntities = null;
}
}
public void Dispose()
{
RemoveContext();
}
}
W moim repozytorium używam kontekstu bazy danych tak:
public class SomeRepository
{
private static readonly object Lock = new object();
private readonly dbEntities _dbEntities;
public SomeRepository()
{
var databaseContext = new DatabaseContext();
_dbEntities = databaseContext.GetDatabaseContext();
}
public IEnumerable<SomeRecord> GetSomeData(int id)
{
lock (Lock)
{
return
_dbEntities.SomeData.Where(c => c.Id == id);
}
}
}
Blokada (Lock) było to coś czytałem o powinno pomóc ten problem, ale w moim przypadku tak się nie stało. I generalnie trudno było znaleźć wątki, które opisują dokładnie mój problem, nie mówiąc już o rozwiązaniu problemu.
Aplikacja jest aplikacją ASP.NET MVC3 i jest skonfigurowana jako jedna aplikacja uruchomiona na 9 różnych stronach internetowych (domena określa treść, która ma być wyświetlana klientowi). 9 witryn nie ma więcej niż 2000 odsłon dziennie, więc baza danych powinna być akcentowana na tym koncie.
Mam nadzieję, że ktoś może pomóc i proszę dać mi znać, jeśli jest coś, o czym zapomniałem wspomnieć.
Co wywołuje 'DatabaseContext.Dispose()'? Używam podobnego ustawienia 'HttpContext.Items' i mam' HttpModule', który zrzuca 'ObjectContext' na końcu żądania ... –
Właściwie myślałem, że' Dispose() 'został wywołany automatycznie, ponieważ implementuje' DatabaseContext' 'IDisposable'. Ale jeśli nie, to z pewnością może wyjaśnić błąd. Czy mogę rzucić okiem na twój kod w 'HttpModule'? – hylle