与EF代码优先和静态表的多对多关系

时间:2013-01-15 09:43:50

标签: c# entity-framework ef-code-first entity-framework-5

我正在使用Entity Framework 5和代码优先方法。

我有一个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是从viewmodel对象创建的,无论是第一次创建时,还是以后编辑时都是:

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

创建时,它们会像这样保存在数据库中:

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

编辑时就像这样:

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

EF最初会生成ProductsProductColorProductProductColor表。首次创建和保存产品时,颜色将正确保存在ProductProductColor表中。

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

对于冗长的帖子感到抱歉,但我希望包含所有元素,以防有人需要完整的图片。

1 个答案:

答案 0 :(得分: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时,无法跟踪对集合的更改。