Entity Framework Element Code First Method AddOrUpdate insert Duplicate Values

I have a simple object:

public class Hall { [Key] public int Id {get; set;} public string Name [get; set;} } 

Then in the Seed method, I use AddOrUpdate to populate the table:

 var hall1 = new Hall { Name = "French" }; var hall2 = new Hall { Name = "German" }; var hall3 = new Hall { Name = "Japanese" }; context.Halls.AddOrUpdate( h => h.Name, hall1, hall2, hall3 ); 

Then I launch the package management console:

 Add-Migration Current Update-Database 

Everything is in order: I have three rows in the Hall table. But if I run the Update-Database package management console again, I already have five lines:

 Id Name 1 French 2 Japaneese 3 German 4 French 5 Japanese 

Why? I think it should be three lines again, not five. I tried using the Id property instead of Name , but that doesn't matter.

UPDATE:

This code gives the same result:

 var hall1 = new Hall { Id = 1, Name = "French" }; var hall2 = new Hall { Id = 2, Name = "German" }; var hall3 = new Hall { Id = 3, Name = "Japanese" }; context.Halls.AddOrUpdate( h => h.Id, hall1); context.Halls.AddOrUpdate( h => h.Id, hall2); context.Halls.AddOrUpdate( h => h.Id, hall3); 

I also have the latest EntityFramework installed via nuget.

+48
c # entity-framework-4
Apr 04 2018-12-12T00:
source share
10 answers

Ok, I hit me on the keyboard for an hour with this. If the table ID field is the Identification field, then it will not work, so use expressionExpression for the expression. I used the Name property and also removed the Id field from the new Hall {...} initializer new Hall {...} .

This setting for OPs code worked for me, so I hope this helps someone:

 protected override void Seed(HallContext context) { context.Halls.AddOrUpdate( h => h.Name, // Use Name (or some other unique field) instead of Id new Hall { Name = "Hall 1" }, new Hall { Name = "Hall 2" }); context.SaveChanges(); } 
+49
Mar 14 '13 at 15:51
source share

This code works:

 public Configuration() { AutomaticMigrationsEnabled = true; } protected override void Seed(HallContext context) { context.Halls.AddOrUpdate( h => h.Id, new Hall { Id = 1, Name = "Hall 1" }, new Hall { Id = 2, Name = "Hall 2" }); context.SaveChanges(); } 
+9
Nov 20
source share

I know this is an old question, but the correct answer is that if you set id # yourself and want to use AddOrUpdate, then you need to tell EF / SQL that you do not want it to generate the identifier #.

 modelBuilder.Entity<MyClass>().Property(p => p.Id) .HasDatabaseGeneratedOption(System.ComponentModel .DataAnnotations.Schema.DatabaseGeneratedOption.None); 

The downside of this is that when you insert a new element, you need to set its Id, so if this is done dynamically at runtime (instead of seed data), you will need to calculate the next identifier. Context.MyClasses.Max(c=>c.Id) + 1 works well.

+8
Jan 22 '16 at 17:55
source share

This can also be caused if you set the Entity state incorrectly. I kept getting the following error when starting the update database ... "The sequence contains several matching items."

For example, I created duplicate rows for each update-database command (which, of course, should not happen when sowing data), and then the next update database command will not work at all, because it found more than one match (therefore, sequence error indicating that I have multiple matching lines). This is because I overridden SaveChanges in my context file with a call to the ApplyStateChanges method ...

 public override int SaveChanges() { this.ApplyStateChanges(); return base.SaveChanges(); } 

I used ApplyStateChanges to ensure that when adding object graphs, the Entity Framework explicitly knows whether the object is in an added or changed state. All explanation of how I use ApplyStateChanges can be found here .

And this works fine (but beware !!) ... if you also host the database using CodeFirst migration, then the above method will cause chaos for calling AddOrUpdate () in the seed method. Therefore, before anything else, just check the DBContext file and make sure that you do not override SaveChanges above, or you will get a second copy of the duplicate data executing the update-database command, and then you won’t work at all for the third time, because for each corresponding An item has more than one row.

When it comes to this, you don’t need to configure the Id in AddOrUpdate () ..., which defeats the whole purpose of a simple and initial seed database. It works fine with something like:

 context.Students.AddOrUpdate( p => p.StudentName, new Student { StudentName = "Bill Peters" }, new Student { StudentName = "Jandra Nancy" }, new Student { StudentName = "Rowan Miller" }, new Student { StudentName = "James O'Dalley" }, 

just AS LONG, since I am not overriding the SaveChanges method in my context file with a call to ApplyStateChanges. Hope this helps.

+3
Jul 28 '13 at 21:24
source share

I found that AddOrUpdate works great with fields that are not identifiers. If this works for you: context.Halls.AddOrUpdate(h => h.Name, hall1, hall2, hall3)

You might want to use Hall names such as "French_test_abc_100", "German_test_abc_100", etc.

This stops hard-coded test data when you test your application.

+1
Nov 03 '12 at 20:27
source share

If the id of the object (hall) is 0, this is an insert. I think you need to double check the id field of your hall objects

0
Apr 04 2018-12-12T00: 00Z
source share

Is the ID field the Identification field? I ran into this problem. When I removed the Identity status from my ID field and set the identifiers included in the database, this fixed the problem.

This worked for me, as these were lookup tables and, in any case, should not have been identity fields.

0
May 08 '12 at 15:54
source share

I think it is likely that you need to undo existing database migrations (i.e. start your database from scratch) with something like "Update-Database TargetMigration: 0" followed by "Update-Database".

Be that as it may, you are not discarding the existing table or values, you are just adding / updating these values. This must happen to get the desired result.

Here's a good link for EF migration: http://elegantcode.com/2012/04/12/entity-framework-migrations-tips/

0
Mar 03 '15 at 1:15
source share

I used the ID field as Identity / Key and added attributes to not assign identifiers to the server. This solved the problem for me.

 public class Hall { [Key] [Required] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id {get; set;} public string Name [get; set;} } 
0
Nov 24 '16 at 11:00
source share

For Ciaren's answer only, the ModelCreating context reset code below helped me solve similar problems. Make sure you change "ApplicationContext" to your DbContext name.

 public class ApplicationContext : DbContext, IDbContext { public ApplicationContext() : base("ApplicationContext") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); Database.SetInitializer<ApplicationContext>(null); base.OnModelCreating(modelBuilder); } } 
0
Aug 09 '17 at 11:06 on
source share



All Articles