Reputation: 137
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.
Upvotes: 1
Views: 105
Reputation: 39386
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();
}
Upvotes: 1