JK.*_*JK. 5 c# entity-framework objectcontext
在ASP.NET MVC 2中,使用Entity Framework 4,我收到此错误"实体对象不能被IEntityChangeTracker的多个实例引用".
对SO的搜索表明,可能是因为我有不同的Entity Framework 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;
}
Run Code Online (Sandbox Code Playgroud)
我已经检查了这段代码,看起来是正确的.据我所知,它为每个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();
}
}
Run Code Online (Sandbox Code Playgroud)
我的猜测是你在内存中存储了一个对象(很可能是使用进程内模式的http缓存,但也可能是任何手动缓存,如共享字典),现在你已经以某种方式将该对象与某个东西相关联否则,例如:
newOrder.OwnerUser = currentUser; // <== let's say currentUser came from cache
// and newOrder was on your new entity context
Run Code Online (Sandbox Code Playgroud)
因此,如果缓存的对象仍然认为它附加到上下文,则会出现问题; 不仅如此,您可能会意外地保留整个图表.
代码看起来没问题(只要你在请求结束时处理它),但这是添加的好时机:
private const string EFContextKey = "EF.ObjectContext";
Run Code Online (Sandbox Code Playgroud)
并使用它代替5个文字.避免一些风险; p
| 归档时间: |
|
| 查看次数: |
2777 次 |
| 最近记录: |