Autonumber с Entity Framework

Я хочу перебрать коллекцию объектов и добавить их все в таблицу. Таблица назначения имеет поле автоматического увеличения. Если я добавлю один объект, проблем нет. Если я добавлю два объекта как с первичным ключом, равным нулю, инфраструктура сущности завершается с ошибкой. Я могу вручную указать первичные ключи, но все, что нужно, чтобы попробовать EF, было сделать жизнь проще не сложнее. Ниже приведен код и полученное исключение.

foreach (Contact contact in contacts)
{               
    Instructor instructor = InstructorFromContact(contact);             
    context.AddToInstructors(instructor);               
}

try
{                   
    context.SaveChanges();                  
}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}

Ошибка:

System.InvalidOperationException. Изменения в базе данных были успешно завершены, но произошла ошибка при обновлении контекст объекта. Объект ObjectContext может находиться в несогласованном состоянии. Внутреннее сообщение об исключении: AcceptChanges не может продолжаться, поскольку значения ключа объекта конфликтуют с другим объектом в ObjectStateManager. Убедитесь, что значения ключа уникальны до вызов AcceptChanges. в Параметры System.Data.Objects.ObjectContext.SaveChanges(SaveOptions)
в System.Data.Objects.ObjectContext.SaveChanges() at DataMigration.Program.CopyInstructors() в C:\Projects\DataMigration\Program.cs: строка 52

Ответы

Ответ 1

Установите для атрибута StoreGeneratedPattern значение "Identity" в вашем SSDL для поля автоинкремента. Это должно помочь.

Ответ 2

Это происходит потому, что, несмотря на то, что автоматически созданное значение столбца было создано в базе данных, EF никогда не знала об этом.

Итак, чтобы сообщить EF, что БД будет обрабатывать сгенерированное значение, вы должны открыть файл edmx (я всегда использую XML-редактор VS для этого) и в области языка определения схемы хранилища (SSDL), добавьте атрибут StoreGeneratedPattern = "Identity" в столбец, которому нужен сгенерированный шаблон. Таким образом, EF считывает значение, сгенерированное в БД, и сохраняет его в кеше памяти.

Определение типа вашей сущности будет выглядеть примерно так:

 <EntityType Name="INVOICE">
          <Key>
            <PropertyRef Name="CODE" />
          </Key>
          <Property Name="CODE" Type="varchar" Nullable="false"
              MaxLength="10" StoreGeneratedPattern="Identity"/>                 
 </EntityType>

Помните, что если вам случится обновить вашу модель, все эти изменения будут потеряны, и вам придется повторить весь процесс.

Это работает для EF 1.0, я не уверен, что в EF4 все эти проблемы уже исправлены.

Ответ 3

Я использую EF6, чтобы установить StoreGeneratedPattern, вы также можете попробовать открыть файл EDMX в Visual Studio, щелкнуть правой кнопкой мыши по столбцу данных в таблице и выбрать "Свойства",

Затем вы можете установить его с None на Identity в окне свойств: