4

我使用 MYSql 服务器作为我的 Windows 窗体应用程序后面的数据库。我的数据库中有两个模式,我必须将条目放入其中。我为每个模式创建了两个上下文对象。当我使用 schema1 上的 contextA 时,所有条目都完美完成,但是当我使用 contextB 时,我得到了这个异常。它与MySql Driver有关吗?

4

3 回答 3

9

此错误表示您正在尝试将一个实体附加到您的上下文,但它已经附加到另一个。

我怀疑这可能不是直接引用,但可能您的上下文中的导航属性之一包含一个附加到另一个上下文的实体。在我看来(根据您的描述),只有在它们是不连贯的对象结构时才应该真正使用单独的上下文,例如它们在上下文之间没有 FK。

要避免的另一件事是确保对于每个工作单元,您只使用每个上下文的一个实例。如果您尝试使用另一个上下文实例中的实体,也会发生此错误。

编辑:

如果您想在当前上下文之外维护范围,通常使用 ID 是一个更好的主意。您可以将实体重新附加到 EF,以便您可以按照您描述的方式添加它们,但您必须确保原始上下文已处理或实体已分离,然后手动将其附加到新上下文,如下所示:

    public DbEntityEntry<T> EnsureAttachedEF(T entity)
    {
        var e = m_Context.Entry(entity);
        if (e.State == EntityState.Detached)
        {
            m_Context.Set<T>().Attach(entity);
            e = m_Context.Entry(entity);
        }

        return e;
    }

然而,这是一项相当多的工作,因此使用 ID 通常是一个更好的主意。

于 2013-06-05T13:02:10.070 回答
4

它几乎肯定是由代理和更改跟踪引起的。在两个构造函数中禁用这些功能,看看它是否能解决您的问题。

public class contextA : DbContext
{
   public contextA()
   {
      Configuration.ProxyCreationEnabled = false;
   }
}
于 2013-06-05T08:08:22.733 回答
2

将评论移至 anwser:

看来您可能在 EF 上下文之外使用实体。这将导致无法跟踪对实体的更改。同时,EF 会缓存该实体,如果您尝试将该实体附加到上下文,它将看到它已经存在并抛出错误。

如果您在上下文之外使用实体,则可以使用 EF 中的NoTracking选项来阻止 EF 缓存实体。

于 2013-06-05T17:53:32.177 回答