В ASP.NET MVC 2 при использовании Entity Framework 4 я получаю сообщение об ошибке «На объект сущности нельзя ссылаться из нескольких экземпляров IEntityChangeTracker».
Поиск SO показывает, что это, вероятно, связано с тем, что у меня есть разные экземпляры ObjectContext Entity Framework, тогда как для каждого HttpContext должен быть только один экземпляр ObjectContext.
У меня есть этот код (написанный задолго до того, как я присоединился), который, похоже, делает только это - иметь один ObjectContext для каждого HttpContext. Но я часто получаю исключение «IEntityChangeTracker», поэтому оно, вероятно, работает не так, как предполагалось:
// in ObjectContextManager.cs
public const string ConnectionString = "name=MyAppEntities";
public const string ContainerName = "MyAppEntities";
public static ObjectContext GetObjectContext()
{
ObjectContext objectContext = GetCurrentObjectContext();
if (objectContext == null) // create and store the object context
{
objectContext = new ObjectContext(ConnectionString, ContainerName);
objectContext.ContextOptions.LazyLoadingEnabled = true;
StoreCurrentObjectContext(objectContext);
}
return objectContext;
}
private static void StoreCurrentObjectContext(ObjectContext objectContext)
{
if (HttpContext.Current.Items.Contains("EF.ObjectContext"))
HttpContext.Current.Items["EF.ObjectContext"] = objectContext;
else
HttpContext.Current.Items.Add("EF.ObjectContext", objectContext);
}
private static ObjectContext GetCurrentObjectContext()
{
ObjectContext objectContext = null;
if (HttpContext.Current.Items.Contains("EF.ObjectContext")
objectContext = (ObjectContext)HttpContext.Current.Items["EF.ObjectContext"];
return objectContext;
}
Я изучил этот код, и он выглядит правильно. Насколько я могу судить, он возвращает один экземпляр ObjectContext для каждого HttpContext. Код неправильный?
Если код не является неправильным, почему еще я мог бы получить исключение «На объект сущности не могут ссылаться несколько экземпляров IEntityChangeTracker»?
РЕДАКТИРОВАТЬ: Чтобы показать, как размещается ObjectContext:
// in HttpRequestModule.cs
private void Application_EndRequest(object source, EventArgs e)
{
ServiceLocator.Current.GetInstance<IRepositoryContext>().Terminate();
}
// in RepositoryContext.cs
public void Terminate()
{
ObjectContextManager.RemoveCurrentObjectContext();
}
// in ObjectContextManager.cs
public static void RemoveCurrentObjectContext()
{
ObjectContext objectContext = GetCurrentObjectContext();
if (objectContext != null)
{
HttpContext.Current.Items.Remove("EF.ObjectContext");
objectContext.Dispose();
}
}