I’m using Entity Framework 5, and a code first approach.
I have a Product class, which can have zero-or-more ProductColors. The colors are prepopulated in the database using seeding. The color table should not be populated with new items using EF as it is a static list of items that will not grow. Colors are reused in many products.
My model classes:
public class Product
{
public int ID { get; set; }
public string Title { get; set; }
public virtual ICollection<ProductColor> Colors { get; set; }
}
public class ProductColor
{
public int ID { get; set; }
public string Title { get; set; }
}
In my DbMigrationsConfiguration:
protected override void Seed(... context)
{
context.ProductColors.AddOrUpdate(
p => p.ID,
new ProductColor(1, "White"),
new ProductColor(2, "Black"),
new ProductColor(3, "Red"));
}
In my DbContext:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().HasMany(x => x.Colors).WithMany();
}
public DbSet<Product> Products { get; set; }
My Products are created from a viewmodel object, both when they are created for the first time, and also later when they are edited:
Product product = new Product { ID = productViewModel.ID };
product.Colors = new List<ProductColor>();
foreach (int colorId in productViewModel.SelectedColorIds)
{
ProductColor productColor = productColors.Find(m => m.ID == colorId);
product.Colors.Add(productColor);
}
They are saved in the database like this when created:
db.Products.Add(product);
db.SaveChanges();
And like this when they are edited:
db.Entry(product).State = EntityState.Modified;
db.SaveChanges();
EF generates Products, ProductColor and ProductProductColor tables just fine initially. When the products are first created and saved, the colors are properly being saved in the ProductProductColor table.
But when I edit/modify the Product and Colors collection, the colors are not being updated in the database. Seems it doesn’t recognize that the Colors collection has been modified. How can I make it so?
Sorry for the lengthy post, but I wanted to include all the elements in case someone needs the full picture.
I managed to find a solution. Instead of create a new
Productinstance (using the same ID as previously), I fetch the product from the database.When I then change the
Colorscollection, it seems the tracking of items is working and serialized correctly into the database.After some reading to understand why, I see fetching the product from the database creates a Proxy object that keeps track of the collection for me. When creating a
Productmanually, it is not able to track changes to collections.