Сам Отслеживание Объектов - AcceptChanges не может продолжиться, потому что значения ключа объекта конфликтуют с другим объектом в ObjectStateManager

Я застревал с этой проблемой больше недели теперь. Надо надеяться, кто-то может указать на меня в правильном направлении.

Я запускаю с краткого описания своей схемы.

Актив 1---> 1 Адрес *-> 1 область *-> 1 регион *-> 1 Страна

Пакет 1-> * Актив

Использование Самого отслеживания объекта (STE) + WCF.

Шаги:

  1. Данные вызова хранят для списка активов.
  2. Данные вызова хранят для списка пакетов.
  3. Пользователь выбирает пакет, и присвойте некоторые активы ему.
  4. Сохраните пакет.

На шаге 2 вызов использует нетерпеливую загрузку Адресов.

from p in context.Assets.Include("Address.Area.Region.Country")

Это - ошибка при попытке звонить

context.Packages.ApplyChanges(package)

AcceptChanges не может продолжиться, потому что значения ключа объекта конфликтуют с другим объектом в ObjectStateManager. Удостоверьтесь, что значения ключа уникальны прежде, чем назвать AcceptChanges.

Править

После отслеживания вокруг, я нашел, что это - проблема STE. Так как проблема - Вы, не может сохранить график, который содержит несколько экземпляров того же объекта, как обрисовано в общих чертах здесь. Вот мой вопрос.

Как я могу добавить объект к своему набору объекта. Новый объект, возможно, связал объекты, которые уже содержат тот же ключ как один в наборе. Т.е. Добавьте новый актив, который может содержать тот же адрес, область, регион или объект страны.

Вот, мой ограничивает:

  1. Я должен использовать навигационный набор, потому что он влияет на UI.
  2. Я не могу выбрать с упреждением все объекты, которые будут включены, потому что набор данных просто слишком большой.
  3. Я должен смочь взять снимки объекта в любое время, чтобы сохранить историю и использовать ее для "отменения" любых изменений.

Я знаю о возможных решениях, предложенных Diego B Vega, но это не опции, которые я могу использовать для своего решения. У кого-либо есть какие-либо другие идеи?

12
задан Tri Q Tran 1 August 2010 в 07:20
поделиться

2 ответа

Думали ли вы просто отказаться от ORM и вернуться к нормальному доступу, если вы понимаете, что я имею в виду: -)

Не шучу - к тому времени, когда вы будете бороться с одним синглом проблема, подобная этой (которая больше всего пахнет ошибкой ORM), вы могли бы развернуть свои собственные 5-10 функций для выполнения обычных вызовов sproc и более простого преобразования типов данных, а затем вы вернетесь к полному контролю и не застрянете библиотеками, для стабилизации которых потребуется еще около 5 лет.

Тем более, что у вас очень чистая схема, то есть довольно простые запросы и прямые обновления.

8
ответ дан 2 December 2019 в 18:17
поделиться

Я столкнулся с той же проблемой и, наконец, нашел решение. Основная идея состоит в том, чтобы предотвратить присоединение определенного типа навигационного класса к ObjectContext. Вот что я сделал:

  1. Изменил шаблон context.tt, чтобы сделать класс SelfTrackingEntitiesContextExtensions частичным.
  2. Скопируйте 2 функции ApplyChanges во вновь созданный Custom.Context.Extension.cs и переименуйте их в CustomApplyChanges. У каждого будет один дополнительный параметр в виде массива типа

public static void CustomApplyChanges (это Контекст ObjectContext, строка entitySetName, объект TEntity, Тип [] excludeTypes ), где TEntity: IObjectWithChangeTracker

  1. Добавьте условие в цикл for для исключения любого типа класса, содержащегося в массиве excludeTypes.

region Handle Initial Entity State

foreach (IObjectWithChangeTracker changedEntity в entityIndex.AllEntities.Where (x => x.ChangeTracker.State == ObjectState.Deleted && ! ExcludeTypes.Contains (x.GetType ()))) {HandleDeletedEntity (контекст, entityIndex, allRelationships, changedEntity); }

foreach (IObjectWithChangeTracker changedEntity в entityIndex.AllEntities.Where (x => x.ChangeTracker.State! = ObjectState.Deleted && ! excludeTypes.Contains (x.GetType ()))) {HandleEntity (контекст, entityIndex, allRelationships, changedEntity); }

endregion

  1. Использование

Тип [] excludeTypes = {typeof (Актив), typeof (Адрес), typeof (Регион)};

rep.Entities.CustomApplyChanges (entity, excludeTypes); var changedEntry = rep.Context.ObjectStateManager.GetObjectStateEntries> (System.Data.EntityState.Added | System.Data.EntityState.Modified | System.Data.EntityState.Deleted); foreach (var e в changedEntry) { если (excludeTypes.Any (c => c == e.Entity.GetType ())) { rep.Context.Detach (e.Entity); // отключаем неизмененные объекты } }

3
ответ дан 2 December 2019 в 18:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: