简体   繁体   中英

Entity Framework many to many - Code First - Migrations

I have Product class:

public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Language> Languages { get; set; }
}

Language class:

public class Language
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Product> Products { get; set; }

}

In my EntityTypeConfiguration:

public class ProductMap : EntityTypeConfiguration<Product>
{

    public ProductMap()
    {
        HasKey(m => m.Id);
        Property(p => p.Name).IsRequired();

       HasMany(p => p.Languages)
            .WithMany(l => l.Products)
            .Map(x => x.ToTable("ProducLanguages")
                .MapLeftKey("ProductId")
                .MapRightKey("LanguageId"));

        //Table  
        ToTable("Products");
    }
}

This creates a third table as expected, but when I executed my update-database with the following seed:

protected override void Seed(EcoomerceContext context)
    {
        var languages = new List<Language>
        {
            new Language {Name = "Portuguese"},
            new Language {Name = "English"},
            new Language {Name = "Spanish"}
        };

        var languagePt = new List<Language>
        {
            new Language {Name = "Portuguese"},
        };

        //languages.ForEach(a => context.Languages.Add(a));

        new List<Product>
        {
          new Product {Name = "NameProduct1", Languages = languages},
          new Product {Name = NameProduct2 , Languages = languagePt},
        }.ForEach(a => context.Products.Add(a));

        context.SaveChanges();
    }

It updates the relationship table ProducLanguages like this:

在此处输入图片说明

It is inserting a language that does not exist (number 4), the result I expect is:

在此处输入图片说明

What Am I doing wrong ?

Thanks in advance.

You need to specify the Id of each entity, even if the PK is Identity. Specifying Id which will be used in database is crucial otherwise each Update-Database will create new records.

Also you should use the AddOrUpdate extension method which was created for seeding data during migrations.In this method you can specify an expression to know what property should be used to check if it's necessary perform an Add or an Update operation, but if you don't specify the Id in your entities, a new row will be added and the old one will also remain. So at the end, your Seed method could be this way:

 protected override void Seed(ConsoleApplication3.YourContext context)
 {
        var languages = new[]
        {
            new Language {Id = 1, Name = "Portuguese"},
            new Language {Id = 2, Name = "English"},
            new Language {Id = 3, Name = "Spanish"},
            new Language {Id = 4, Name = "French"},
        };

        // This way you can add all the languages even when there is not associated to a product
        // The first parameter is an expression to know what properties should be used when determining whether an Add or Update operation should be performed
        context.Languages.AddOrUpdate(l => l.Name, languages);

        var products = new[]
        {
            new Product {Id = 1, Name = "NameProduct1", Languages = new List<Language> {languages[0],languages[1],languages[3]}},
            new Product {Id = 2, Name = "NameProduct2", Languages = new List<Language> {languages[0]}},
        };
        context.Products.AddOrUpdate(p=>p.Name,products);

        context.SaveChanges();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM