Как избавиться от объекта "Объект сущности не может ссылаться на несколько экземпляров IEntityChangeTracker"?
У меня есть модель в Ado.Net EF.
У меня отношение от одного до большого, и когда я хочу добавить сущности, я получаю ошибку
"Объект сущности не может быть связан несколькими экземплярами IEntityChangeTracker"
Любая подсказка?
Нечто похожее на
Template template = new Template();
...
...
while (from < to)
{
Course course = new Course();
.....
template.Course.Add(course);
.....
}
courseEntities.AddToTemplate(template); // Problem line
courseEntities.SaveChanges();
Ответы
Ответ 1
Я получал это сообщение, пока не начал хранить контекст данных в HttpContext.Items. Это означает, что вы можете использовать один и тот же контекст данных для текущего веб-запроса. Таким образом, вы не получаете 2 контекста данных, ссылающихся на те же объекты.
Вот хороший пост в DataContext Life Management.
Надеюсь, это поможет.
Dave
Ответ 2
"шаблон", или что-то, что он ссылается, уже добавлен к курсовым событиям или другому контексту. Я ничего не вижу в коде, который вы показываете, он будет делать это, но это, безусловно, происходит. Возможно, это происходит в некотором коде, который вы урезали. Посмотрите на свойство EntityState "template" в отладчике и посмотрите на EntityState свойств "шаблона". Это должно помочь вам выяснить, какой экземпляр объекта уже находится в контексте.
Ответ 3
Я уже понимаю проблему. У меня есть другое отношение, и я получаю другой объект из другого контекста.
Ответ 4
Позвольте мне рассказать о моем опыте с этой неприятной ошибкой и указать, что местность, преследующая ее, приведет вас к тому, что приведет к чрезвычайно простому решению.
Компания GroupGroup довольно проста. Он имеет имя и имеет объект компании.
Я начал с этого:
1 public static void Add(CompanyGroup item)
2 {
3 try
4 {
5 using (Entities scope = new Entities())
6 {
7 scope.AddToCompanyGroup(item);
8 scope.SaveChanges();
9 }
10 }
11 catch (Exception ex)
12 {
13 LogException(ex, item);
14 throw;
15 }
16 }
И получил эту ошибку:
{ "Объект сущности не может быть на которые ссылаются множественные экземпляры IEntityChangeTracker." }
Итак, я добавил это между строками 6 и 7:
(IEntityWithChangeTracker)item).SetChangeTracker(null);
Это вознаградило меня:
{ "Объект нельзя добавить в ObjectStateManager, потому что он уже имеет EntityKey. использование ObjectContext.Attach для присоединения объект, имеющий существующий ключ." }
Итак, я изменил
scope.AddToCompanyGroup(item);
to
scope.Attach(item);
Теперь он жаловался:
{ "Объект с временным EntityKey значение не может быть привязано к объекту контекст." }
(начинают звучать, как некоторые из девушек, которых я встречал в юности - никогда не довольствуюсь - но я отвлекаюсь)
Итак, я сделал ключ сущности null (не работал) и использовал метод для создания нового (тоже не работал)
По пути я тоже получил эту ошибку:
{ "Исходный запрос для этого EntityCollection или EntityReference не могут быть возвращены, когда соответствующие объект находится либо в добавленном состоянии, либо в отсоединенное состояние и не было изначально извлекается с использованием NoTracking merge option." }
Решение?
Замените ядро, строки 7 и 8, с помощью
CompanyGroup newcg = new CompanyGroup();
newcg.GroupName = item.GroupName;
newcg.Company = scope.Company.Where(c => c.CompanyID == item.Company.CompanyID).First();
scope.AddToCompanyGroup(newcg);
scope.SaveChanges();
По сути, я взял данные, переданные через "элемент", и переместил их на вновь созданный объект того же типа, который вводит тот же тип
как тот, который используется в Add.
Ответ 5
Надеюсь, это самое простое и правильное решение. Вам нужен один db-контекст для httprequest.
Код EF4 Первый шаблон Global.asax.cs
http://gist.github.com/574505
void MvcApplication_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Items[SessionKey] = new Db();
}
void MvcApplication_EndRequest(object sender, EventArgs e)
{
var disposable = HttpContext.Current.Items[SessionKey] as IDisposable;
if (disposable != null)
disposable.Dispose();
}
Ответ 6
Эта проблема была решена путем удаления из объекта, который я обновляю, дополнительных отношений с другими объектами (Virtual). Оставлены только их идентификаторы.
Это неправильный код
dataFileEntity.IterParameterValue = parameterValueEntity.ParameterValue;
dataFileEntity.IterParameterValueId = parameterValueEntity.ParameterValue.Id;
dataFileEntity.ResultParameter = parameterValueEntity.ResultParameter;
dataFileEntity.ResultParameterId = parameterValueEntity.ResultParameter.Id;
dataFileEntity.RawDataResult = result.Value;
Это правильно.
dataFileEntity.IterParameterValueId = parameterValueEntity.ParameterValue.Id;
dataFileEntity.ResultParameterId = parameterValueEntity.ResultParameter.Id;
dataFileEntity.RawDataResult = result.Value;
RequestTestRawDataFileRepository.AddOrUpdate(dataFileEntity);
Я эту проблему решила, убрав из объекта, который я апдейтила лишние связи с другими сущностями (Virtual). Оставила только их id.
Ответ 7
Пожалуйста, инициализируйте свои объекты только один раз.
Как
Если вы несколько раз инициализируете свои сущности.
Вы получите сообщение об ошибке:
Объект сущности не может ссылаться на несколько экземпляров IEntityChangeTracker.
Пример:
public class Test
{
private Entities db=new Entities();
public static void Add(CompanyGroup item)
{
try
{
db.CompanyGroup.Add(item);
db.SaveChanges();
}
catch (Exception ex)
{
}
}
}