60885

“An error occurred while updating the entries” in EF when I try to SaveChanges() to context

Question:

I've created two lists that corresponds to two of my classes:

//Photo var photos = new List<Photo>{ new Photo { Title = "Title1", Description = "Description1", CreatedDate = DateTime.Today } }; //Comment var comments = new List<Comment> { new Comment{ PhotoId = 1, UserName = "User1", Subject = "Comment1", } };

When I tried to add these two lists to my context object and then SaveChanges, I got the error I mentioned:

photos.ForEach(s => context.Photos.Add(s)); comments.ForEach(s => context.Comments.Add(s)); context.SaveChanges();

But when I saved the changes individually, I didn't get the exception.

photos.ForEach(s => context.Photos.Add(s)); context.SaveChanges(); comments.ForEach(s => context.Comments.Add(s)); context.SaveChanges();

Why is this? Should I save changes after each modification of my DB?

Answer1:

To avoid issues like this, set up the relationships between your entities and use those relationships rather than trying to set FK IDs manually. ORMs like EF are designed to work this detail out for you, so leverage that ability.

If a photo has comments, where a comment has a PhotoID column then set up the entities something like this:

public class Photo { public int PhotoID {get; set;} public string Title {get; set;} public string Description {get; set;} private List<Comment> _comments = new List<Comment>(); public virtual List<Comment> Comments { get {return _comments;} set {_comments = value;} } } public class Comment { public string UserName {get; set;} public string Subject {get; set;} }

Note that I haven't added PhotoID to comment. If you want to search for comments for instance and navigate back to a Photo then you can optionally add:

public virtual Photo Photo {get; set;}

However if you don't need that navigation, then I'd avoid adding it to keep things simple.

To set up these navigation properties so EF can manage them, I use EntityTypeConfiguration mappings. There are also methods using data annotations, but I find ETConfigs more reliable.

public class PhotoConfiguration : EntityTypeConfiguration<Photo> { public PhotoConfiguration() { ToTable("Photos"); HasKey(x => x.PhotoID) .Property(x => x.PhotoID) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); // This informs EF that the database will be assigning the PK. HasMany(x => x.Comments) .WithRequired() .Map(x => x.MapKey("PhotoID")); // This tells EF to join comments to a Photo /w the PhotoID on the Comment table. HasMany says a Photo has many comments, and WithRequired() points to a non-nullable FK on Comment, but no navigation property coming back to Photo. } }

This example is for EF6, for EFCore you can replace the .Map() call /w

.HasForeignKey("PhotoID");

which will accomplish the same thing with a shadow property. If you do want a reference to Photo on each Comment, then you can add the virtual property in Comment, then replace the .WithRequired() with .WithRequired(x => x.Photo) and this will set up the relationship.

public class CommentConfiguration : EntityTypeConfiguration<Comment> { public CommentConfiguration() { ToTable("Comments"); HasKey(x => x.CommentID) .Property(x => x.CommentD) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); } }

Now when you want to save a photo and a comment:

var photo = new Photo { Title = "Title1", Description = "Description1", CreatedDate = DateTime.Today, Comments = new[] { New Comment { UserName = "User1", Subject = "Comment1" } }.ToList() }; context.Photos.Add(photo); context.SaveChanges();

Note that we don't save Comments separately. EF manages all of the PK/FK behind the scenes. After the SaveChanges we can retrieve the PKs of our entities from the entity properties.

Recommend

  • Index on every Foreign Key?
  • Finding the related FK property of a Navigation Property
  • How to extend Relationship class in neo4django
  • Modify a Google App Engine entity id?
  • Jhipster: How to create relationships with User entity using supplied tools?
  • HTML code to upload images
  • JPA/EclipseLink Returning No Results
  • Injecting service into a mixin Ember2.3+
  • SQL - count occurrences of gender
  • NSMutableArray Access Issue
  • Nodejs bluebird promise fails while processing image
  • Copying rows in a database when rows have children
  • Neo4j: Legacy Indexes and auto index vs new label bases schema indexes
  • How can I see a list of all files that are different between two Hg repositories?
  • Insertion large number of Entities into SQL Server 2012 [duplicate]
  • Receiver has no segue with identifier“***”
  • Are there any side effects from calling SQLAlchemy flush() within code?
  • hibernate sets dirty flag (and issues update) even though client did not change value
  • Updating Dojo provide
  • SonarQube: Cannot deactivate rule with missing quality profile
  • Clarification on min distance on LocationManager.requestLocationUpdates method, min Distance paramet
  • How to generate and display a QR Code in ionic 2
  • Force show.bind execution
  • how to avoid repetitive constructor in children
  • How can I extract results of aggregate queries in slick?
  • Needing to do .toArray() to get output of mongodb .find() on key name not value
  • How to get Eclipse Oxygen to run on Java 9
  • Do I need to reset a Perl hash index?
  • Use of this Javascript
  • Atlas images wrong size on iPad iOS 9
  • MongoDB in PHP using aggregate to group by _id is null not working
  • Control modification in presentation layer
  • How to set the response of a form post action to a iframe source?
  • Change div Background jquery
  • Turn off referential integrity in Derby? is it possible?
  • How does Linux kernel interrupt the application?
  • Qt: Run a script BEFORE make
  • reshape alternating columns in less time and using less memory
  • git trying to push non-existent file … after clearing cache
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize