在 ASP.NET MVC 2 中,使用实体框架 4,我收到此错误“实体对象无法被 IEntityChangeTracker 的多个实例引用”。
对 SO 的搜索表明,这可能是因为我有不同的实体框架 ObjectContext 实例,而每个 HttpContext 应该只有一个 ObjectContext 实例。
我有这段代码(在我加入之前很久就写好了),它似乎就是这样做的——每个 HttpContext 都有一个 ObjectContext。但我经常收到“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;
}
我已经检查过这段代码,它看起来是正确的。据我所知,它为每个 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();
}
}
我的猜测是,您已经在内存中的某个位置存储了一个对象(很可能是使用进程内模式的http缓存,但也可能是任何手动缓存,例如共享字典),现在您已经以某种方式将该对象与某些东西关联起来否则,例如:
newOrder.OwnerUser = currentUser; // <== let's say currentUser came from cache
// and newOrder was on your new entity context
因此,如果缓存的对象仍然认为它附加到上下文,就会出现问题;尤其重要的是,您可能会意外地使整个图表保持活动状态。
代码看起来不错(只要您在请求末尾处理它),但这将是添加的好时机:
private const string EFContextKey = "EF.ObjectContext";
并用它代替 5 个文字。避免一些风险;p
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)