简体   繁体   English

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

[英]Many-to-many relationship with EF code first and static table

I'm using Entity Framework 5, and a code first approach. 我正在使用Entity Framework 5和代码优先方法。

I have a Product class, which can have zero-or-more ProductColors . 我有一个Product类,可以有零个或多个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. 颜色表不应使用EF填充新项目,因为它是不会增长的静态项目列表。 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 : 在我的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 : 在我的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: “我的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);
}

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. EF最初生成ProductsProductColorProductProductColor表就很好。 When the products are first created and saved, the colors are properly being saved in the ProductProductColor table. 首次创建和保存产品时,颜色已正确保存在ProductProductColor表中。

But when I edit/modify the Product and Colors collection, the colors are not being updated in the database. 但是,当我编辑/修改“ ProductColors集合时,数据库中的颜色没有更新。 Seems it doesn't recognize that the Colors collection has been modified. 似乎无法识别Colors集合已被修改。 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 Product instance (using the same ID as previously), I fetch the product from the database. 我没有创建新的Product实例(使用与以前相同的ID),而是从数据库中获取了产品。

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

When I then change the Colors collection, it seems the tracking of items is working and serialized correctly into the database. 然后,当我更改Colors集合时,似乎对项目的跟踪正在工作并正确地序列化到数据库中。

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. 经过一番阅读以了解原因之后,我看到从数据库中获取产品会创建一个Proxy对象,该对象会为我跟踪集合。 When creating a Product manually, it is not able to track changes to collections. 手动创建Product ,它无法跟踪对集合的更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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