2010-06-10 3 views
15

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

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() в DataMigration.Program.CopyInstructors() в C: \ Projects \ DataMigration \ Program.cs : строка 52

+3

Я предполагаю, что если вы просто оставить поле пустым Autonumber, база данных будет назначить для вас, когда вы совершаете. –

+0

Да, он работает, он добавляет записи и назначает первичные ключи, проблема в том, что я не должен получать исключение для такого типичного сценария. Я уверен, что есть «правильный» способ сделать это в рамках, просто не уверен, как это сделать. – dcompiled

+0

Ну, теперь исключение перестало быть брошенным после того, как я внесла некоторые изменения в таблицу и обновил модель. Не уверен, что изменило ситуацию. Единственные изменения, которые я сделал, это добавить некоторые значения по умолчанию для столбцов и установить для этих столбцов значение не равно нулю. Не уверены, что изменения связаны с исключением. – dcompiled

ответ

18

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

+7

Обратите внимание, что вы не можете просто установить это свойство в конструкторе, вам нужно вручную отредактировать раздел SSDL. Я прочитал этот ответ и подумал: «Я уже это сделал», и я продолжал искать, я мог бы сэкономить часы, заметив * SSDL * Это ошибка в дизайнере. http://geeksharp.com/2010/05/27/ef4-bug-in-storegeneratedpattern-ssdl/ и http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/404d3017-01b7 -4129-8e05-f4aa48f15f08 – DanO

+0

Вы можете захотеть взвесить на этом: http://meta.stackexchange.com/questions/82509/should-accounts-used-by-multiple-users-be-allowed/82519#82519 – smartcaveman

+0

@Devart это, не решить для меня .. – Campinho

12

Это происходит потому, что, несмотря на то, что автогенерированное значение столбца было создано в базе данных, 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 все эти проблемы уже исправлены.

+2

Я думаю, где я ошибался, так это то, что я изначально создал модель из базы данных и забыл установить поле autonumber. Позже я отредактировал мою базу данных и установил это свойство, а затем команду «обновить модель из базы данных» в visual studio 2010. Функция обновления, похоже, добавляет новые свойства, но не совсем уверен, правильно ли она исправляет существующие модифицированные свойства. Удалив мою модель и воссоздавая с нуля, функция автонабора работала, как ожидалось. Однако, если бы я знал лучше, я бы попробовал вашу идею. – dcompiled

+0

В настоящее время (но, надеюсь, скоро!) Я не использую EF4, однако я прочитал что-то на этой странице, где говорится об этом: http://geeksharp.com/2010/05/27/ef4-bug-in-storegeneratedpattern-ssdl/ – cepriego

+2

Корпорация Майкрософт предлагает исправление для VS2010SP1. http://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=37957 Кажется, это работает для меня. – kimsk

2

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

Тогда вы можете установить его из None в Identity в окне Свойства:

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