На объектный объект нельзя ссылаться несколькими экземплярами IEntityChangeTracker - PullRequest
1 голос
/ 29 октября 2011

У меня есть модель под названием Сообщение.В этой модели есть ICollection ResourceSubscribeers другой модели под названием Resource.Когда я пытаюсь

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);"строка выдает InvalidOperationException с сообщением «На объект сущности нельзя ссылаться несколькими экземплярами IEntityChangeTracker.».

Ответы [ 3 ]

2 голосов
/ 08 марта 2012

Если вы используете тот же самый контекст в любом месте, где лучше использовать контекст в качестве экземпляра синглтона.

Это обеспечит наличие у класса только одного экземпляра и предоставит глобальную точку доступа к нему

Проверьте это: http://www.dofactory.com/Patterns/PatternSingleton.aspx#_self1

0 голосов
/ 09 октября 2014

Это старый вопрос, но я решил опубликовать свой ответ на тот случай, если он кому-нибудь поможет.

Я столкнулся с такой же проблемой в своем коде MVC, даже используя шаблон единиц работы, как уже упоминалось.Элад Бенда.Я обнаружил, что мой ресурс DbContext не освобождается в конце вызова контроллера.

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

Затем удалите класс 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 похож на хранилище.Наконец, метод DetachAll () в производном классе DbContext выглядит следующим образом:

    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.Он ссылается на Tests, который ссылается на список TestsDtc.Обратите внимание, я сохраняю эти связи ссылок, так как корень моего дерева объектов будет сохранен, но DbContext освободит остальные, когда они отсоединятся.

Я бы хотел сделать это более общим, но это сработало.Надеюсь, это поможет.

0 голосов
/ 29 октября 2011

Используете ли вы другой контекст в GetResourceById для получения ресурсов?В этом случае эти объекты связаны с этим контекстом.При выполнении Context.Messages.Add вы пытаетесь связать объекты с другим контекстом, который не разрешен.

Все связанные операции, которые выполняются вместе, должны использовать один и тот же контекст.Наличие нескольких контекстов порождает проблемы.

...