IEntityChangeTracker的多个实例不能引用实体对象

时间:2011-10-29 06:33:28

标签: .net asp.net-mvc-3 invalidoperationexception

我有一个名为Message的模型。在模型中,有一个名为Resource的另一个模型的ICollection ResourceSubscribers。当我尝试

public void SaveMessage(List<int> subscribers)
    {
        Condition.Requires(model).IsNotNull();
        Message model = new Message();

        //Some assignments to initialize the model

        ICollection<Resource> res = new List<Resource>();

        foreach (var item in subscribers)
        {
            res.Add(this.ResourceService.GetResourceById(item));
        }

        model.ResourceSubscribers = res;
        Context.Messages.Add(model);
        Context.SaveChanges();
    }

“Context.Messages.Add(model);” line抛出InvalidOperationException,并显示消息“IEntityChangeTracker的多个实例无法引用实体对象。”。

3 个答案:

答案 0 :(得分:2)

如果您使用相同的Context,那么最好将上下文用作单例实例。

这将确保一个类只有一个实例并提供一个全局访问点

请检查:http://www.dofactory.com/Patterns/PatternSingleton.aspx#_self1

答案 1 :(得分:0)

您是否在GetResourceById中使用其他上下文来获取资源?在那种情况下,这些对象与该上下文相关联。在执行Context.Messages.Add时,您尝试将对象与另一个不允许的上下文相关联。

一起发生的所有相关操作应使用相同的上下文。周围有多个背景是问题。

答案 2 :(得分:0)

这是一个老问题,但我想我会发布我的答案,以防有人帮助。

我在MVC代码中遇到了同样的问题,甚至使用了Elad Benda提到的工作单元模式。我发现在控制器调用结束时没有释放我的DbContext资源。

    using (_DatabaseUow)
    {
        // your controller code that accesses the database here.
    } // When this goes out of scope dispose is called.

然后Dispose databaseUnitOfWork类

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing == true)
        {
            _ObdDbContext.DetachAll();
            _ObdDbContext = null;
            _ObdBusinessData = null;
        }
    }

    ~DatabaseUnitOfWork()
    {
        Dispose(false);
    }

_ObdBusinessData成员类似于存储库。最后,DbContext派生类中的DetachAll()方法如下所示:

    public void DetachAll()
    {
        var entries = SetTestsOnlineData.Local;
        while (entries.Count != 0)
        {
            TestsOnlineData tod = entries[0];
            Tests tro = entries[0].Tests;
            List<TestsDtc> dtcs = entries[0].Tests.TestsDtcs.ToList();

            foreach (TestsDtc dtc in dtcs)
                Detach(dtc);
            Detach(entries[0].Tests);
            Detach(entries[0]);

            tro.TestsDtcs = dtcs;
            tro.TestsOnlineData = tod;
            tod.Tests = tro;
        }
    }

    public void Detach(object entity)
    {
        ((IObjectContextAdapter)this).ObjectContext.Detach(entity);
    }

我使用了我的实体/对象的特定知识来分离内存中的所有内容。我有一个名为TestsOnlineData的表。它链接到测试链接到TestsDtc列表。请注意,我保留了这些链接关系,因为我的对象树的根将被保留,但DbContext将在分离时释放其他链接。

我本来希望这个更通用,但这很有用。我希望这会有所帮助。