C# Entity Framework 每个 HttpContext 只使用一个 ObjectContext

标签 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;
}

我检查了这段代码,它看起来是正确的。据我所知,它会为每个 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

关于C# Entity Framework 每个 HttpContext 只使用一个 ObjectContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6688772/

相关文章:

c# - 我们可以在不使用客户端 key 的情况下从 azure 获取 key 值吗?

c# - 如何使用特定的用户名和密码启动 IIS 进程

c# - 如何在 Visual Studio 中为字体类型使用 DefaultValueAtribute 类?

c# - EF6 : Configure complex mapping for entities (code first)

c# - .NET Entity Framework Core、依赖注入(inject)和线程的 DBContext System.ObjectDisposed 异常

c# - 如何从 Entity Framework 中获取架构名称?

C# 返回工厂默认值

c# - 通过 NuGet 管理器安装 EntityFramework

c# - EF 中的 ObjectMaterialize 未在第一级查询上触发

entity-framework-4 - Entity Framework 更新 - 上下文当前未跟踪实体