C # Entity «На объектный объект нельзя ссылаться несколькими экземплярами IEntityChangeTracker.» - PullRequest
0 голосов
/ 13 декабря 2011

Поэтому я пытаюсь удалить некоторые элементы из базы данных, прежде чем вставить некоторые данные. По какой-то причине C # Entity Framework и ASP.NET не любят, когда я выполняю эту простую операцию, и выдает еще одну из этих смутных ошибок.

Я пытаюсь обновить набор строк информации в таблице (используя циклы foreach и Insert / Delete), а также некоторые свойства в другой таблице (используя обновление)

Как это исправить? Ошибка происходит в функции Delete, в строке: this.entities.tableModule.Attach (модуль);

Я получаю: «System.InvalidOperationException: объект сущности не может ссылаться несколькими экземплярами IEntityChangeTracker.»

public void Insert(tableModule module)
    {
        this.entities.tableModule.AddObject(module);
        this.entities.SaveChanges();
    }    
public void Delete(tableModule module)
    {
        this.entities.tableModule.Attach(module); // error HERE
        this.entities.DeleteObject(module);
        this.entities.SaveChanges();
    }

Далее код, который я называю «Удалить, вставить и обновить» для другой таблицы.

try
        {
            DifferentClass.Update(tu);
            foreach (tableModule mitem in list_to_del)
            {
                moduleclass.Delete(mitem); // remove all super roles by the user.
            }
            foreach (tableModule m_to_add in add_list)
            {
                moduleclass.Insert(m_to_add);
            }
        }

Из того, что я понял, функция присоединения, возможно, запускается более одного раза, и по какой-то причине разработчики C # Entity Framework полностью застигнуты врасплох и поэтому выдают ошибку. Хотя, скорее всего, это мое полное непонимание структуры сущностей.

EDIT: Вот как я могу получить массив list_to_del.

List<tableModule> list_to_del = (from m in entities.tableModule where m.userid == (long)userID select m).ToList(); 

EDIT2:

Новый тестовый код:

public void InsertQueue(tableModule module)
{
    this.entities.tableModule.AddObject(module);
}
public void DeleteQueue(tableModule module)
{
    this.entities.tableModule.Attach(module);
    this.entities.DeleteObject(module);
}
public void FinallySave(){
    this.entities.SaveChanges();
}

РЕДАКТИРОВАТЬ 3 ---- РЕШЕНИЕ -----

Тестовый код работал вроде (хотя вставки не по какой-то странной причине). Проблема заключалась в том, что я вызывал запрос list_to_del, чтобы получить этот массив tableModules из класса tableUser, который имеет свой собственный набор / контекст сущности. Таким образом, результаты в list_to_del были другого контекста, чем вызов класса, который выполняет DeleteQueue / Insert и т. Д.

Я изменил:

List<tableModule> list_to_del = (from m in entities.tableModule where m.userid == (long)userID select m).ToList(); 

соответствующему классу с тем же запросом:

List<tableModule> list_to_del = ModuleClass.GetListofModulesByUserID(userID);

Конечно ModuleClass.InsertQueue и ModuleClass.DeleteQueue вызывается.

Так что все используют один и тот же объект сущностей (context / entityset).

Таким образом, ошибка возникает при вызове запроса в контексте, который возвращает набор результатов, которые УЖЕ прикреплены к этому контексту. Затем, когда вы снова вызываете Attach, возникает проблема, потому что они уже находятся в контексте какого-то другого класса / экземпляра.

1 Ответ

2 голосов
/ 13 декабря 2011

Вам не нужно вызывать Attach, если вы загрузили модуль из того же экземпляра контекста - вы можете вызвать DeleteObject напрямую.Когда вы загружаете сущность из контекста, она по умолчанию отслеживается контекстом (= она прикреплена), и вы не можете присоединить ее снова.Вы также не можете присоединить его к другому контексту, поэтому убедитесь, что list_to_del загружен тем же экземпляром контекста, который вы используете для удаления (= он должен быть загружен при той же обработке запроса, поскольку у вас должен быть новый экземпляр контекста для каждого запроса).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...