2011-02-23 2 views
7

У меня есть простая модель с «BaseEntity» и производным объектом «Фонд». При попытке вставить новый фонд:Entity Framework 4: Таблица для типа проблемы наследования при вставке

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

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

"Cannot insert the value NULL into column 'Id', table 'HybridData.dbo.BaseEntities'; column does not allow nulls. INSERT fails.
The statement has been terminated."

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

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

enter image description here

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

+0

Что такое 'HybridModelContainer'? Опубликуйте снимок экрана с данными сопоставления для вашего объекта 'Fund'. –

+0

Это просто имя DataContext. – SolarX

+0

@SolarX: Не могли бы вы опубликовать скриншот, который я упомянул? –

ответ

9

Я могу ответить только на вторую часть вашего вопроса: «Также ... почему в моем DataContext (т. Е. Container.Funds) нет объекта ObjectSet для« фондов »?»

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

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

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

(Первая часть вашего вопроса звучит как ошибка отображения между хранением и концептуальной моделью Это может иметь лучший СИФ вас может показать соответствующие части файла EDMX)

Edit:. Возможное решение первой части вопроса:

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

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

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

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

+0

Спасибо. Я пробовал то же самое с базовым подходом базы данных, и все работает (после удаления отношений и настройки наследования в модели). Я просто не могу заставить это работать с «модельным первым» подходом. Но мы хотим сначала пойти на модель. Есть идеи? – SolarX

+0

@SolarX: Возможно, я нашел решение: см. Редактировать в моем ответе выше. – Slauma

+0

Я попробую это, как только я получу свои встречи ... Я ожидал, что это проблема с Гидом. Любопытно, что я ничего не мог найти в Интернете. Большое вам спасибо за вашу помощь !! – SolarX

Смежные вопросы