ObjectContext.SaveChanges () нарушает первичный ключ, выбрасывает UpdateException?

Перефразируя изэта документация MSDN ...

Инструкция INSERT генерируется Entity Framework и выполняется в источнике данных, когда SaveChanges вызывается для ObjectContext.

Если операция INSERT выполнена успешно, сгенерированные сервером значения записываются обратно в ObjectStateEntry. Когда AcceptChanges вызывается автоматически в конце выполнения SaveChanges, постоянный EntityKey вычисляется с использованием новых сгенерированных сервером значений.

Это, кажется, не происходит в моем коде. Когда я звонюObjectContext.SaveChanges(),UpdateException брошен сInnerException.Message значение:

"дубликат значения ключа нарушает уникальное ограничение student_term_data_pkey"

Вот оскорбительный код:

using (DataAccessLayerEntities context = new DataAccessLayerEntities()) {
     StudentTermData mostCurrent = new StudentTermData() {
          // Foreign keys:    
          StudentId = studentId,
          TermId = currentTerm.Id,

          // Non-nullable properties:
          SponsorCode = string.Empty,
          AdmissionNumber = string.Empty,
          Expiration = string.Empty
     };

     context.StudentTermDatas.AddObject(mostCurrent);
     context.SaveChanges();  // UpdateException occurs here.
}

Я подтвердил, чтоStudentTermData.Id помечен как EntityKey в моей модели данных Entity. У кого-нибудь есть идеи или предложения?

 Rob09 сент. 2010 г., 22:19
Кроме того, я не уверен, что вы имеете в виду в своем первом комментарии. Вы хотите схему для student_term_data? Или просто запрос INSERT, который генерируется?
 Rob09 сент. 2010 г., 22:17
Идентификатор студента получен как есть из SelectedValue ComboBox, который не привязан к коллекции студентов, поэтому я не использую mostCurrent.Students.Add (student). Кроме того, термин передается в качестве аргумента функции после загрузки отдельным ObjectContext.
 Ian Mercer09 сент. 2010 г., 18:57
Можно ли использовать DDL для StudentTermData, в частности поле Id, на самом деле он генерируется на сервере?
 Ian Mercer09 сент. 2010 г., 18:59
Любая причина, по которой вы используете поля Id и добавляете StudentTermData в objectContext вручную вместо простогоmostCurrent.Students.Add(student) а такжеmostCurrent.Term = currentTerm после создания экземпляра этого? (Предполагая, что вы можете использовать один objectContext, чтобы загрузить их и применить их)

Ответы на вопрос(2)

Решение Вопроса

когда разработчик EF не устанавливает атрибут StoreGeneratedPattern в SSDL. Проблема задокументирована вэтот блог а такжеэтот билет Microsoft Connect.

Решением было открыть файл .edml моей модели в текстовом редакторе, найти<EntityType Name="student_term_data"> XML-тег и добавитьStoreGeneratedPattern="Identity" чтобы тег свойства использовался в качестве EntityKey:

  <EntityType Name="student_term_data">
     <Key><PropertyRef Name="id" /></Key>
     <Property Name="id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
     ...
  </EntityType>

Затем я снова открыл свою модель в конструкторе EF, сделал небольшое изменение (переместил позицию объекта) и сохранил. Это вызвало запуск генератора кода, предположительно синхронизируя CDSL с SSDL.

Мой код теперь работает как ожидалось.

 Rob10 сент. 2010 г., 20:56
В заявке Майкрософт есть еще один обходной путь, в котором используется стороннее программное обеспечение для сравнения моделей для синхронизации SSDL и CDSL без необходимости вручную изменять XML.

РЕДАКТИРОВАТЬ

Если вы пытаетесь выполнить вставку, не заполняйте поле PK (полагаю, это StudentID).

 Rob07 сент. 2010 г., 21:00
Извините, я должен был уточнить. Первичный ключ просто называется Id, StudentId - это внешний ключ.

Ваш ответ на вопрос