Lukasz
Lukasz

Reputation: 15

How avoid adding duplicates to database managed by Entity Framework caused by Seed?

Every time I run the application same objects are added to the database (duplicates).

My Configuration.cs:

namespace SklepInternetowy1.Migrations
{
    using SklepInternetowy1.DAL;
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    public sealed class Configuration : DbMigrationsConfiguration<SklepInternetowy1.DAL.KursyContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
            ContextKey = "SklepInternetowy1.DAL.KursyContext";
        }

        protected override void Seed(SklepInternetowy1.DAL.KursyContext context)
        {
            KursyInitializer.SeedKursyData(context);
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //
        }
    }
}

My KursyInitializer.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using SklepInternetowy1.Models;
using SklepInternetowy1.DAL;
using SklepInternetowy1.Migrations;
using System.Data.Entity.Migrations;

namespace SklepInternetowy1.DAL
{
    public class KursyInitializer : MigrateDatabaseToLatestVersion<KursyContext, Configuration>
    {
        public static void SeedKursyData(KursyContext context)
        {
            var kategorie = new List<Kategoria>
            {
                new Kategoria() {KategoriaID=1, NazwaKategorii="Asp123",NazwaPlikuIkony="asp.png", OpisKategorii="opis asp net mvc" },
                new Kategoria() {KategoriaID=2, NazwaKategorii="Java",NazwaPlikuIkony="java.png", OpisKategorii="opis java" },
                new Kategoria() {KategoriaID=3, NazwaKategorii="Php",NazwaPlikuIkony="php.png", OpisKategorii="opis php" },
                new Kategoria() {KategoriaID=4, NazwaKategorii="Html",NazwaPlikuIkony="html.png", OpisKategorii="opis html" },
                new Kategoria() {KategoriaID=5, NazwaKategorii="Css",NazwaPlikuIkony="css.png", OpisKategorii="opis css" },
                new Kategoria() {KategoriaID=6, NazwaKategorii="Xml",NazwaPlikuIkony="xml.png", OpisKategorii="opis xml" },
                new Kategoria() {KategoriaID=7, NazwaKategorii="C#",NazwaPlikuIkony="c#.png", OpisKategorii="opis c#" }
             };

            kategorie.ForEach(k => context.Kategorie.AddOrUpdate(k));
            context.SaveChanges();

            var kursy = new List<Kurs>
            {
                new Kurs() {AutorKursu="Tomek", TytulKursu="asp.net mvc1", KategoriaID=1, CenaKursu=100, Bestseller=true, NazwaPlikuObrazka="asd.png", DataDodania=DateTime.Now, OpisKursu="opis1" },
                new Kurs() {AutorKursu="Jacek", TytulKursu="asp.net mvc2", KategoriaID=2, CenaKursu=101, Bestseller=true, NazwaPlikuObrazka="asd1.png", DataDodania=DateTime.Now, OpisKursu="opis2" },
                new Kurs() {AutorKursu="Jarek", TytulKursu="asp.net mvc3", KategoriaID=3, CenaKursu=102, Bestseller=true, NazwaPlikuObrazka="asd2.png", DataDodania=DateTime.Now, OpisKursu="opis3" },
                new Kurs() {AutorKursu="Romek", TytulKursu="asp.net mvc4", KategoriaID=4, CenaKursu=103, Bestseller=true, NazwaPlikuObrazka="asd3.png", DataDodania=DateTime.Now, OpisKursu="opis4" }
            };

             kursy.ForEach(k => context.Kursy.AddOrUpdate(k));
             context.SaveChanges();
        }
    }
}

My Kurs.cs:

namespace SklepInternetowy1.Models
{
    public class Kurs
    {
        public int KursID { get; set; }
        public int KategoriaID { get; set; }
        [Required(ErrorMessage = "Wprowadz nazwę kursu")]
        [StringLength(100)]
        public string TytulKursu { get; set; }
        [Required(ErrorMessage = "Wprowadz nazwę autora")]
        [StringLength(100)]
        public string AutorKursu { get; set; }
        public DateTime DataDodania { get; set; }
        [StringLength(100)]
        public string NazwaPlikuObrazka { get; set; }
        public string OpisKursu { get; set; }
        public decimal CenaKursu { get; set; }
        public bool Bestseller { get; set; }
        public bool Ukryty { get; set; }
        public string OpisSkrocony { get; set; }

        public virtual Kategoria Kategoria { get; set; }

    }
}

Every time I run the app, Seed adds duplicate records:

duplicates

Question: what must I change to avoid duplicates in the table Kurs?

Upvotes: 1

Views: 1025

Answers (2)

Nikita K
Nikita K

Reputation: 406

As stated in the AddOrUpdate MSDN article this method uses the key property to check the existence of an entity. In your case, the default value for the integer property is 0. So the EF checks whether there is a record with such key and decided that it should create a new record for the entity. So, you need to explicitly define the KursID property in the seed method for each record in order to make Entity Framework know that the related item already persists in the data base when the AddOrUpdate is executed.

Upvotes: 1

Nowshad Rahaman
Nowshad Rahaman

Reputation: 81

You forgot to bind the key(s) for which the seed method will check either it is an add or update.

Just change the following line......

kursy.ForEach(k => context.Kursy.AddOrUpdate(x => x.AutorKursu, k));

I am assuming that "AutorKursu" is your primary key. You can setup this condition as you like & depending on that lamda function seed method will determine the require action.

From Entity Framework doc:

 identifierExpression:
        //     An expression specifying the properties that should be used when determining
        //     whether an Add or Update operation should be performed.

MSDN: https://msdn.microsoft.com/en-us/library/hh846514(v=vs.103).aspx

Upvotes: 1

Related Questions