Entity Framework - пытается вставить нулевые значения при создании нового объекта - PullRequest
0 голосов
/ 15 июля 2011

У меня та же проблема, что и у некоторых из вас - при попытке вставить новый объект EF вставляет нулевые значения для некоторых их свойств, и вставка завершается неудачей.

Сначала позвольте мнеопишите структуру нашей БД.Это система управления событиями, в которой каждое событие должно быть связано с тренировочной группой, хранящееся в таблице кеша, но в конечном итоге полученное из Active Directory.Я вручную создал таблицу соединений - это проблема?В любом случае, у Event есть внешний ключ, указывающий на EventPracticeGroup, который имеет внешний ключ, указывающий на PracticeGroupCache.PracticeGroupCache также имеет RegionId, указывающий на таблицу Regions.

Проблема возникает при попытке вставить новый объект EventPracticeGroup.Ниже приведен код, который я сейчас использую:

var eventPracticeGroup = new EventPracticeGroup();
if (TryUpdateModel<EventPracticeGroup>(eventPracticeGroup))
{
    /*
    var eventId = EventScheduleRepository.GetById(Convert.ToInt32(Request.QueryString["EventScheduleId"])).EventId;
    eventPracticeGroup.Event = EventRepository.GetById(eventId);
    eventPracticeGroup.PracticeGroupCache = PracticeGroupCacheRepository.GetById(eventPracticeGroup.PracticeGroupCacheId);
    eventPracticeGroup.PracticeGroupCache.Region = RegionRepository.GetById(eventPracticeGroup.PracticeGroupCache.RegionId);
    EventPracticeGroupRepository.Add(eventPracticeGroup);
    */

    var eventId = EventScheduleRepository.GetById(Convert.ToInt32(Request.QueryString["EventScheduleId"])).EventId;
    var theEvent = new Event() { Id = eventId };
    EventRepository.Repository.UnitOfWork.Context.AttachTo("Events",theEvent);
    var practiceGroupCache = new PracticeGroupCache() { Id = eventPracticeGroup.PracticeGroupCacheId };
    practiceGroupCache.Region = new Region() { Id = eventPracticeGroup.PracticeGroupCache.RegionId };
    eventPracticeGroup.PracticeGroupCache = practiceGroupCache;
    EventPracticeGroupRepository.Add(eventPracticeGroup);
    EventPracticeGroupRepository.Save();
    return RedirectToAction("Index");
}

В любом случае ... как вы можете видеть, я только что попытался использовать объекты-заглушки (без помощи), и я также попытался на самом деле получить иустановка объектов.Я получаю следующую ошибку:

Невозможно вставить значение NULL в столбец «Имя», таблица «XXXX.dbo.Regions»;столбец не допускает пустых значений.Вставить не удается.Оператор был прерван.

Очевидно, что имя не является ключевым полем.Я проверил EDMX XML - только для Id (столбцы первичного ключа) для StoreGeneratedPattern установлено значение Identity, как и должно быть (это столбцы идентификаторов int32).Ни в одном внешнем ключе для StoreGeneratedPattern не задано значение identity.

Если я задаю для Regions.Name пустые значения, PracticeGroupCaches.Description выдает такую ​​же ошибку.Кажется, что каждый связанный объект устанавливается в нуль.Я взглянул на отладчик, когда использовал закомментированный код, ничего не было нулевым и все имело значение.Я даже получил RegionRepository, чтобы вернуть все регионы, просто чтобы посмотреть, есть ли у одного из них где-нибудь нулевое имя.Ни один не сделал.В моей тестовой БД всего 2.Наш контекст объекта является общим для каждого HTTP-запроса.

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

С уважением, Джонатан.

Ответы [ 2 ]

0 голосов
/ 15 июля 2011

Посмотрите, что происходит, когда вы звоните по этой линии:

EventPracticeGroupRepository.Add(eventPracticeGroup);

Вы добавляете новый eventPracticeGroup в контекст. Но eventPracticeGroup имеет другие связанные объекты:

eventPracticeGroup -> PracticeGroupCache -> Region

И вы создаете новые объекты для них:

var practiceGroupCache = new PracticeGroupCache() {
    Id = eventPracticeGroup.PracticeGroupCacheId };
practiceGroupCache.Region = new Region() {
    Id = eventPracticeGroup.PracticeGroupCache.RegionId };
eventPracticeGroup.PracticeGroupCache = practiceGroupCache;

Когда вы добавляете eventPracticeGroup к контексту, добавляется весь этот граф объектов, что означает, что EF рассматривает все три объекта как новые, которые должны быть добавлены в БД. Поскольку вы заполняете только свойства Id, другими строковыми свойствами (например, Name или Description) являются null. Из-за того, что они не обнуляются в базе данных, команда INSERT не выполняется.

Но я думаю, что вы все равно не хотите вставлять связанные сущности в БД, а только eventPracticeGroup. Поэтому вам нужно прикрепить их к контексту перед добавлением нового объекта, например:

var practiceGroupCache = new PracticeGroupCache() {
    Id = eventPracticeGroup.PracticeGroupCacheId };

EventRepository.Repository.UnitOfWork.Context.AttachTo(
   "PracticeGroupCaches",practiceGroupCache);

practiceGroupCache.Region = new Region() {
    Id = eventPracticeGroup.PracticeGroupCache.RegionId };

EventRepository.Repository.UnitOfWork.Context.AttachTo(
   "Regions",practiceGroupCache.Region);

eventPracticeGroup.PracticeGroupCache = practiceGroupCache;

EventPracticeGroupRepository.Add(eventPracticeGroup);

Кстати, примечание: об этом EventRepository.Repository.UnitOfWork.Context.XXX взгляните на ответ Ладислава Мринки здесь: EF 4.0 Метод расширения IsAttachedTo и ошибка Объект с таким же ключом уже существует

0 голосов
/ 15 июля 2011

Кажется, вы уже нашли проблему и решение.В вашей схеме БД кажется, что столбцы не допускают значений NULL.Поэтому либо измените все эти столбцы, чтобы разрешить NULL, либо не вставляйте null (это то, что вы сейчас пытаетесь сделать)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...