2013-01-15 102 views
0

我正在使用实体框架5和代码优先方法。与EF代码第一和静态表的多对多关系

我有一个Product类,它可以有零个或多个ProductColors。使用播种将颜色预填充到数据库中。颜色表不应该使用EF填充新项目,因为它是不会增长的项目的静态列表。颜色可以在许多产品中重复使用。

我的模型类:

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; } 
} 

在我DbMigrationsConfiguration

protected override void Seed(... context) 
{ 
    context.ProductColors.AddOrUpdate(
     p => p.ID, 
     new ProductColor(1, "White"), 
     new ProductColor(2, "Black"), 
     new ProductColor(3, "Red")); 
} 

在我DbContext

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Product>().HasMany(x => x.Colors).WithMany(); 
} 

public DbSet<Product> Products { get; set; } 

Products从视图模型对象的创建,都当他们是这是第一次创建,也是以后的创建被编辑:

db.Products.Add(product); 
db.SaveChanges(); 

而且像这样,当他们被编辑:

db.Entry(product).State = EntityState.Modified; 
db.SaveChanges(); 

EF产生ProductsProductColorProductProductColor

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); 
} 

创建时,它们被保存在这样的数据库表格最初没有问题。产品首次创建并保存时,颜色正确保存在ProductProductColor表中。

但是当我编辑/修改ProductColors集合时,数据库中的颜色没有更新。似乎它不承认Colors集合已被修改。我怎么能这样做?

对不起,这篇冗长的文章,但我想包括所有的元素,以防万一有人需要完整的画面。

回答

1

我设法找到解决方案。我不是创建一个新的Product实例(使用与以前相同的ID),而是从数据库中获取产品。

IQueryable<Product> products = 
    from p in db.Products.Include("Colors") 
    select p; 
Product product = Enumerable.FirstOrDefault(products, p => p.ID == id); 

当我再更改Colors收集,似乎项目的跟踪工作,并正确序列化到数据库中。

经过一番阅读以理解为什么,我看到从数据库获取产品会创建一个代理对象,用于跟踪我的集合。手动创建Product时,它无法跟踪对集合的更改。