Как избавиться от объекта "Объект сущности не может ссылаться на несколько экземпляров 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)
        {
        }     
    }   
}