在使用Entity Framework 4的ASP.NET MVC 2中,我遇到了这个错误:“无法将实体对象引用多个IEntityChangeTracker实例”。在SO上的搜索显示,这可能是因为我有不同的Entity Framework ObjectContext实例,而每个HttpContext应该只有一个ObjectContext实例。我有这段代码(在我加入之前就已经写好),看起来正是这样 - 每个HttpContext都有一个ObjectContext。但我经常遇到“IEntityChangeTracker”异常,所以它可能没有按预期工作:
我已经检查了这段代码,它看起来是正确的。据我所知,它为每个HttpContext返回一个ObjectContext实例。代码有问题吗?
如果代码没有问题,那么我为什么会得到“实体对象不能被IEntityChangeTracker的多个实例引用”的异常呢?
编辑:为了展示如何处理ObjectContext:
// 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;
}
我已经检查了这段代码,它看起来是正确的。据我所知,它为每个HttpContext返回一个ObjectContext实例。代码有问题吗?
如果代码没有问题,那么我为什么会得到“实体对象不能被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();
}
}