Entity Framework 4: проблема наследования таблиц для типов при вставке - PullRequest
7 голосов
/ 23 февраля 2011

У меня есть простая модель с «BaseEntity» и производной сущностью «Fund».Когда я пытаюсь вставить новый фонд:

HybridModelContainer container = new HybridModelContainer();

//Create new Fund
Fund fund = new Fund();
fund.Id = Guid.NewGuid();
fund.DateCreated = DateTime.Now;
fund.Name = "Fund 1";
fund.Number = 1;
container.BaseEntities.AddObject(fund);

container.SaveChanges();

я получаю следующую ошибку:

"Невозможно вставить значение NULL в столбец" Id ", таблица" HybridData.dbo ".BaseEntities '; столбец не допускает пустых значений. INSERT завершается неудачей.
Оператор завершен. "

Кажется, что идентификатор, присвоенный сущности фонда, не вставлен в таблицу BaseEntity.Почему бы и нет?

Я сделал эту «модель первой».Если я сначала спроектирую базу данных и создаю модель из нее, все работает нормально ... Но мне сначала нужна модель!

enter image description here

Также ... почему нетObjectSet для "Funds" в моем DataContext (то есть container.Funds)?Заранее спасибо за помощь!

1 Ответ

8 голосов
/ 23 февраля 2011

Я могу ответить только на вторую часть вашего вопроса: «Кроме того ... почему в моем DataContext (т.е. container.Funds) нет ObjectSet для« Funds »?»

Этонормально, что ObjectContext имеет только ObjectSet базового класса в вашей иерархии классов.В действительности нет необходимости в ObjectSet производных классов.Для добавления и удаления производных объектов в / из ObjectContext вы можете просто использовать AddObject и DeleteObject методы ObjectSet<BaseEntity> / BaseEntities, как вы уже сделали в своем примере.

Для запроса производныхобъекты, которые вы можете использовать метод OfType ObjectSet.Он возвращает ObjectQuery производного типа, где вы можете строить дальнейшие запросы по:

ObjectQuery<Fund> query = container.BaseEntities.OfType<Fund>();

(Первая часть вашего вопроса звучит как ошибка отображения между хранилищем и концептуальной моделью. Возможно, она лучшеcif вы могли бы показать соответствующие части вашего файла EDMX.)

Редактировать: Возможное решение первой части вопроса:

Я создал ваш пример сПервая модель в VS2010, и я мог воспроизвести ваш вопрос.Кажется, проблема связана с тем, что первичный ключ в вашей модели - это не Int32, а Guid.Когда вы добавляете новую сущность в модель, дизайнер всегда предлагает Int32 в качестве первичного ключа с StoreGeneratedPattern, установленным на Identity.

Если вы измените тип ключа в конструкторе модели сInt32 до Guid, но оставив StoreGeneratedPattern без изменений, равным Identity, DDL создает базу данных в SQL Server с Id, установленным на тип uniqueidentifier, но спецификацией идентификации для этого столбца является "Нет".

Итак, когда EF отправляет команду INSERT в БД, он «думает» из определения модели, что первичный будет автоматически сгенерирован в БД, и не отправляет Guid в БД, которую вы назначили в коде.Но БД не создает ключ, что приводит к значению NULL для ключа.Отсюда получаем ошибку.

Решение: Установите в конструкторе модели для свойства Id для BaseEntity для StoreGeneratedPattern в None.Для меня это сработало тогда.Конечно, вы обязаны всегда назначать Guid на Id, прежде чем добавлять новый объект в ObjectSet, но, похоже, это то, что вам нужно.

...