Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
834 views
in Technique[技术] by (71.8m points)

.net - ObjectContext.SaveChanges() violates primary key, throws UpdateException?

Paraphrasing from this MSDN documentation ...

An INSERT statement is generated by the Entity Framework and executed on the data source when SaveChanges is called on the ObjectContext.

If the INSERT operation succeeds, server-generated values are written back to the ObjectStateEntry. When AcceptChanges is called automatically at the end of the SaveChanges execution, a permanent EntityKey is computed by using the new server-generated values.

This does not seem to be occurring in my code. When I call ObjectContext.SaveChanges(), an UpdateException is thrown with InnerException.Message value:

"duplicate key value violates unique constraint student_term_data_pkey"

Here is the offending code:

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.
}

I have verified that StudentTermData.Id is marked as an EntityKey in my Entity data model. Does anyone have any ideas or suggestions?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This problem was caused by a bug in EF4 where the EF designer doesn't set the StoreGeneratedPattern attribute in the SSDL. The problem is documented in this blog and this Microsoft Connect ticket.

The solution was to open my model's .edml file in a text editor, locate the <EntityType Name="student_term_data"> XML tag, and add StoreGeneratedPattern="Identity" to the property tag being used as an EntityKey:

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

I then re-opened my model in the EF designer, made a small change (moved an entity position) and saved. This caused the code generator to run, presumably synchronizing the CDSL with the SSDL.

My code now runs as expected.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...