Entity Framework CTP 4. "Невозможно вставить значение NULL в столбец" - несмотря на то, что нет значения NULL
Я использую EF CTP 4. У меня есть простое консольное приложение (для тестирования), которое использует EF для вставки некоторых данных в базу данных SQL.
Я столкнулся с проблемой, когда, вставив элемент
using(var context = GetContext())
{
BOB b = new BOB();
b.Id = 1;
context.Bobs.Add(b);
context.SaveChanges();
}
Он выдает ошибку: { "Невозможно вставить значение NULL в столбец" Идентификатор ", таблица" TestDB.dbo.BOB "; столбец не допускает нулей. INSERT не работает.\r\nПриложение завершено." }
В таблице только 1 поле Id int NOT NULL, который является первичным ключом, и не автоматически увеличивающийся идентификатор.
При создании DataContext у меня есть эта конфигурация, которая да срабатывает.
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<BOB>().HasKey(b => b.Id);
builder.Entity<BOB>().MapSingleType().ToTable("BOB");
}
Я также предварительно заполнил эту таблицу, а затем через отладчик смог просмотреть часы, загружая этот объект BOB... так что я на самом деле тупик, так как для того, чтобы загрузить мои BOB, все правильно... однако при вставке нового он сбой...
Ответы
Ответ 1
Вы пытались явно указать StoreGeneratedPattern
?
modelBuilder.Entity<BOB>()
.HasKey(p => p.Id)
.Property(p => p.Id)
.StoreGeneratedPattern = StoreGeneratedPattern.None;
builder.Entity<BOB>().MapSingleType().ToTable("BOB");
Ответ 2
У меня такая же проблема, и это действительно уродливое решение.
[Key]
public Int64 PolicyID { get; set; }
это НЕ автоматический номер
тогда я получаю ту же ошибку.
EF Code First CTP5
после применения этого:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Int64 PolicyID { get; set; }
тогда он будет работать.
Ответ 3
Я использую EF 4.1, Model First и столкнулся с этой проблемой. Вот как я это решил:
При использовании поверхности Model Designer, когда вы создаете Entity, вам нужно определить свойство "Key", по умолчанию оно равно Id, int32.
В моей ситуации я решил использовать Guids для Id, поэтому я бы переключил int32 на Guid. Но если вы проверите этот идентификатор после создания объекта, я увидел, что идентификатор "StoreGeneratedPattern" имеет "идентификатор". Сначала я не думал, что это проблема, но когда я изучил SQL, который использовался для вставки в базу данных, это было немного странно, поскольку он не отправлял мой идентификатор. Срыв!
Но как только я вернулся и изменил "StoreGeneratedPattern" с "identity" на "none", восстановил db и перестроил проект, этот странный { "Невозможно вставить значение NULL в столбец" Id ", таблицу" TestDB ". dbo.BOB '; столбец не допускает нулей. INSERT терпит неудачу.\r\nПриложение завершено." } остановилось.
FYI - при просмотре sql еще немного кажется, что если у вас есть "идентификатор", выбранный для "StoreGeneratedPattern", EF сохраняет объект в db (sans Id), а затем сразу же возвращает идентификатор и сохраняет его обратно ваш объект. т.е. этот выбор для "StoreGeneratedPattern" основан на db для генерации вашего идентификатора, НЕ вашего кода!
Ответ 4
Это случилось со мной, когда в уважаемом столбце (столбце идентификации) в схеме db отсутствовал первичный ключ.
Я экспортировал данные между SQL-серверами, используя инструмент SSMS Export и создавая новую базу данных, но не понимал, что он экспортирует только данные без ключей.
Ответ 5
Не могли бы вы разместить свой код С# для типа BOB? В частности, каков тип свойства "Id"? По соглашению Code First сделает любой proeprty под именем Id или TypeName + Id, который также является "int" идентификатором. Однако мне непонятно, почему в этом случае вы получите исключение, поэтому я хотел бы увидеть определение вашего класса.
В соответствии с вашими другими вопросами использование нескольких типов DbContext в одном проекте полностью поддерживается и должно отлично работать с CTP4 и CTP5.
Ответ 6
Вы также можете использовать
modelBuilder.Entity<BOB>()
.HasKey(p => p.Id)
.Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
builder.Entity<BOB>().MapSingleType().ToTable("BOB");
Ответ 7
Я знаю, что этот вопрос как-то устарел, и уже принятое решение уже найдено, однако я подумал, что было бы полезно, если бы я поделился своими выводами.
У меня была эта ошибка сегодня, потому что я использовал два разных экземпляра одного и того же DataContext
. Я создавал новую модель с некоторыми свойствами - значения для этих свойств были загружены из базы данных с использованием одного экземпляра DataContext
, а затем я пытался подтолкнуть эту вновь создаваемую модель к базе данных, вызывающей сначала Add()
, а затем SaveChanges()
в другом экземпляре DataContext
. После того, как я начал использовать тот же экземпляр, как для получения значений свойств, так и для добавления и сохранения нового объекта, все началось.
Ответ 8
У меня была похожая ситуация, но в моем случае даже off
Identity
не помогло.
Проблема была связана с Первичным ключом, который я пропустил, чтобы добавить в мою модель сущности.
Вот скрипт, который генерировал модель:
CREATE TABLE [im].[SomeGroup]
(
[Id] INT NOT NULL IDENTITY(1,1), -- this is mandatory for EF
[OtherGroupId] INT NOT NULL,
[Title] NVARCHAR(512) NOT NULL
)
Код С# для выше:
Insert(new SomeGroup
{
// I'm not providing Id here, cause it will be auto-generated
SomeGroupId = otherGroup.Id,
Title = otherGroup.Title
});
Вот также некоторое объяснение этого.
Ответ 9
Если вы используете подход базы данных сначала, затем сначала удалите соответствующий объект из диаграммы edmx, а затем обновите модель из базы данных, это, безусловно, решит вашу проблему