Это мой первый пост здесь, поэтому я надеюсь, что все в порядке.
Вот моя проблема: в моей базе данных есть таблица с именем UserTypes .Он имеет:
- ID;
- IsPrivate;
- Parent_ID;
Соответствующими являются первый и третий.У меня есть другая таблица с именем UserTypes_T , которая содержит информацию для различных типов, которая зависит от языка.Поля:
- Language_ID;
- UserType_ID;
- Name;
Я пытаюсь достичь загрузкивсю иерархию из таблицы UserTypes и показать ее в виде дерева (это пока не актуально).Затем, выбрав некоторые типы пользователей, я могу редактировать их в отдельном окне редактирования (имя) и комбинированном окне (родитель).
Все работает нормально, пока я не попытаюсь сохранить изменения в базе данных.EF сгенерировал для меня два класса сущностей для этих таблиц:
Класс для пользовательских типов имеет:
- ID;
- IsPrivate;
- Parent_ID;
- Навигационное свойство для самостоятельной ссылки (0..1);
- Навигационное свойство для дочерних элементов;
- Другое навигационное свойство для UserTypes_Tтаблица (1 .. *);
Класс для переведенной информации имеет:
- UserType_ID;
- Language_ID;
- Имя;
- Навигационное свойство к таблице UserTypes (* .. 1);
- Навигационное свойство к таблице Языки (* .. 1);
Я получаю необходимые данные, используя:
return context.UserTypes.Include("UserTypes_T").Where(ut => ut.IsPrivate==false).ToList();
в моем веб-сервисе WCF.Я могу добавить новые типы пользователей без проблем, но когда я пытаюсь обновить старые, происходят некоторые странные вещи.
Если я обновляю корневой элемент (Parent_ID == null), все работает!Если я обновляю элемент, где Parent_ID! = Null, я получаю следующую ошибку:
AcceptChanges не может продолжаться, поскольку значения ключа объекта конфликтуют с другим объектом в ObjectStateManager.
Я искал по всему интернету и прочитал сообщение в блоге Diego B Vega (и многие другие), но моя проблема в другом.Когда я меняю родительский тип пользователя, я на самом деле меняю свойство Parent_ID, а не свойство навигации.Я всегда стараюсь работать с идентификаторами, а не сгенерированными навигационными свойствами, чтобы избежать проблем.
Я провел небольшое исследование, попытался увидеть, какой граф объектов я получаю, и увидел, что было многодубликаты сущностей:
Корневой элемент имеет список своих дочерних элементов.Каждый дочерний элемент имел обратную ссылку на корень или его родителя и так далее.Ты можешь представить.Поскольку я не использовал эти навигационные свойства, потому что я использовал идентификаторы для получения / установки необходимых мне данных, я удалил их из модели.Точнее говоря, я удалил точки 4 и 5 из класса сущностей UserTypes .Тогда у меня был граф объектов с каждым элементом только один раз.Я попробовал новое обновление, но у меня была та же проблема:
Корневой элемент был обновлен нормально, но элементы, у которых были некоторые родители, выдали то же исключение.
Я увидел, что у меня былосвойство навигации в классе сущности UserTypes_T , указывающее на тип пользователя, поэтому я тоже удалил его.Затем эта ошибка исчезла.Все элементы в графе объектов были уникальными.Но проблема осталась - я мог обновить свой корневой элемент без проблем, но при попытке обновить дочерние элементы (без исключений) я получил исключение нулевой ссылки в сгенерированном классе Model.Context.Extensions:
if (!context.ObjectStateManager.TryGetObjectStateEntry(entityInSet.Item2, out entry))
{
context.AddObject(entityInSet.Item1, entityInSet.Item2);//here!
}
Я пытался обновить только имя (в UserTypes_T ), но ошибка та же.
У меня нет идей, и я пытался решить эту проблемув течение 8 часов, поэтому я буду признателен, если кто-то даст мне идеи или поделится своим опытом.
PS:
Единственный способ, которым мне удалось обновить дочерний объект, - использовать следующий код для извлечения данных:
var userTypes = argoContext.UserTypes.Include("UserTypes_T").Where(ut => ut.IsPrivate==false).ToList();
foreach (UserType ut in userTypes)
{
ut.UserType1 = null;
ut.UserTypes1 = null;
}
return userTypes;
, где UserType1 - это свойство навигации, указывающее на родительский тип пользователя и UserTypes1 - свойство навигации, содержащее список дочернего элемента.Проблема заключалась в том, что EF «исправляет» объекты и изменяет Parent_ID на null .Если я установлю его снова, EF также установит UserTypes1 ... Может быть, есть способ остановить это поведение?