Entity Framework Code First AddOrUpdate method insert Duplicate values

后端 未结 13 1146
清酒与你
清酒与你 2020-12-01 08:52

I have simple entity:

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

    public string Name [get; set;}
}

Then in the S

相关标签:
13条回答
  • 2020-12-01 09:18

    This can also be caused if you're setting the Entity State incorrectly. I kept getting the following error when I'd run update-database..."Sequence contains more than one matching element."

    For example, I had duplicate rows being created on each update-database command (which of course is not supposed to happen when seeding data), and then the next update-database command wouldn't work at all since it found more than one match (hence the sequence error saying I have more than one matching row). That's because I had overridden SaveChanges in my context file with a method call to ApplyStateChanges...

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

    I was using ApplyStateChanges to ensure that when adding object graphs, Entity Framework knows explicitly whether the object is in an added or modified state. The entire explanation on how I'm using ApplyStateChanges can be found here.

    And this works great (but the caveat!!)...if you're also seeding the database using CodeFirst migrations, then the above method will cause havoc for the AddOrUpdate() call within the Seed Method. So before anything else, just check your DBContext file and ensure you're not overriding SaveChanges in the way above, or you will end up getting duplicate data running the update-database command a second time, and then won't work at all the third time since there's more than one row for each matching item.

    When it comes down to it, you don't need to configure the Id in AddOrUpdate()...that defeats the whole purpose of easy and initial database seeding. It works fine by 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 as I'm not overriding the SaveChanges method in my context file with a call to ApplyStateChanges. Hope this helps.

    0 讨论(0)
  • 2020-12-01 09:20

    I have found that AddOrUpdate works fine with fields that are not ID's. If this works for you: context.Halls.AddOrUpdate(h => h.Name, hall1, hall2, hall3)

    You may want to use Hall names like 'French_test_abc_100', 'German_test_abc_100' etc.

    That stops hard coded test data messing things up when you are testing your app.

    0 讨论(0)
  • 2020-12-01 09:31

    I used the ID field as Identity/Key and add attributes not to assign Ids by 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 讨论(0)
  • 2020-12-01 09:34

    These steps worked for me

    1. Delete all the rows in the table.
    2. Reset the incremental identity to 0. DBCC CHECKIDENT (yourtablename, RESEED, 0) (The primary keys specified in the Seed() must match those in the database table so that they do not duplicate.)
    3. Specify the primary keys in the 'seed' method.
    4. Run the Seed() method several times and you check if they duplicated.
    0 讨论(0)
  • 2020-12-01 09:35

    Ok I was banging my face off the keyboard for an hour with this. If your table's Id field is an Identity field then it won't work so use a different one for identifierExpression. I used the Name property and also removed the Id field from the new Hall {...} initializer.

    This tweak to the OPs code worked for me so I hope it 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();
    }
    
    0 讨论(0)
  • 2020-12-01 09:35

    Is your ID field an Identity field? I was running into this same issue. When I removed the Identity status from my ID field and set the IDs going into the database, that resolved the issue.

    That worked for me, since these were look-up tables and shouldn't have been identity fields, anyway.

    0 讨论(0)
提交回复
热议问题