Как избавиться от «На объектный объект нельзя ссылаться несколькими экземплярами IEntityChangeTracker»? - PullRequest
15 голосов
/ 06 марта 2009

У меня есть модель в 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();

Ответы [ 7 ]

17 голосов
/ 07 марта 2009

Я получал это сообщение, пока не начал сохранять контекст данных в свойстве HttpContext.Items . Это означает, что вы можете использовать тот же контекст данных для текущего веб-запроса. Таким образом, вы не получите 2 контекста данных, ссылающихся на одни и те же объекты.

Вот хороший пост на DataContext Life Management .

Надеюсь, это поможет.

Dave

2 голосов
/ 06 марта 2009

«шаблон», или что-то, на что он ссылается, уже добавлен в courseEntities или другой контекст. Я не вижу ничего в коде, который вы показываете, он бы это сделал, но это, безусловно, происходит. Возможно, это происходит в некотором коде, который вы урезали. Посмотрите на свойство EntityState шаблона в отладчике и посмотрите на EntityState свойств шаблона. Это должно помочь вам выяснить, какой экземпляр сущности уже находится в контексте.

1 голос
/ 14 мая 2009

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

CompanyGroup довольно прост. У него есть имя и объект Company.

Я начал с этого:

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);

до

scope.Attach(item);

Теперь жаловались на:

{"Объект с временным EntityKey значение не может быть привязано к объекту контекст. "}

(начинает походить на некоторых девушек, с которыми я встречался в юности - никогда не довольствуюсь - но я отвлекаюсь)

Итак, я сделал ключ сущности пустым (не работал) и использовал метод для создания нового (тоже не работал)

Попутно я тоже получил эту ошибку:

{"Исходный запрос для этого EntityCollection или EntityReference не может быть возвращен, когда связанный объект находится в добавленном состоянии или отдельное государство и не было первоначально получены с использованием Опция слияния NoTracking. "}

Решение?

Заменить ядро, строки 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();

По сути, я взял данные, переданные через 'item', и переместил их во вновь созданный объект того же типа, который представляет тот же самый область как та, которая используется в Add.

1 голос
/ 06 марта 2009

Я уже понимаю проблему. У меня есть другое отношение, и я получаю другую сущность из другого контекста.

0 голосов
/ 11 ноября 2013

Пожалуйста, инициализируйте свои сущности только один раз.

вроде как

Если Вы более одного раза инициализируете свои сущности.

Вы получите ошибку:

На объектный объект нельзя ссылаться несколькими экземплярами 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)
        {
        }     
    }   
}
0 голосов
/ 18 июля 2013

Эта проблема была решена путем удаления из объекта, который я обновляю, дополнительных связей с другими сущностями (виртуальными). Осталось только их удостоверение личности.

Это неправильный код

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);

Виртуальная реальность. Оставила только их id.

0 голосов
/ 11 сентября 2010

Надеюсь, это самое простое и правильное решение. Вам нужен один контекст БД для 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...