【问题标题】:Unsure how to insert item into database using Entity Framework with many to many relationship不确定如何使用具有多对多关系的实体框架将项目插入数据库
【发布时间】:2015-07-29 15:24:45
【问题描述】:

我正在尝试将具有关联类别的产品插入到我的数据库中。一个产品可以属于多个类别,显然一个类别可以有多个产品。当我插入时,我确定我的控制器方法中遗漏了一些东西,但我不确定它是什么。我有一个名为 ProductCategory 的桥接表,其中只有一个 ProductID 和一个 CategoryID。当我进行插入时,该表没有被填充。

这是我正在执行插入的控制器方法:

 [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult EditProduct([Bind(Include = "ID,itemNumber,product,description,active,PDFName,imageName,SelectedCategories")] ProductModel model)
    {
        if (ModelState.IsValid)
        {
            using (var context = new ProductContext())
            {
                context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
                if (model.ID == 0)
                {
                    // Since it didn't have a ProductID, we assume this
                    // is a new Product
                    if (model.description == null || model.description.Trim() == "")
                    {
                        model.description = "Our Famous " + model.product;
                    }
                    if (model.imageName == null || model.imageName.Trim() == "")
                    {
                        model.imageName = model.itemNumber + ".jpg";
                    }
                    if (model.PDFName == null || model.PDFName.Trim() == "")
                    {
                        model.PDFName = model.itemNumber + ".pdf";
                    }
                    Session["dropdownID"] = model.ID;

                    // I think I probably need some additional code here...

                    context.Products.Add(model);
                }
                else
                {
                    // Since EF doesn't know about this product (it was instantiated by
                    // the ModelBinder and not EF itself, we need to tell EF that the
                    // object exists and that it is a modified copy of an existing row
                    context.Entry(model).State = EntityState.Modified;
                }
                context.SaveChanges();
                return RedirectToAction("ControlPanel");
            }
        }
        return View(model);
    }

还有我的产品型号:

public class ProductModel
{
    public int ID { get; set; }

    [Required(ErrorMessage = "Required")]
    [Index("ItemNumber", 1, IsUnique = true)]
    [Display(Name = "Item #")]
    public int itemNumber { get; set; }

    [Required(ErrorMessage = "Required")]
    [Display(Name = "Product")]
    [MaxLength(50)]
    public String product { get; set; }

    [Display(Name = "Description")]
    [MaxLength(500)]
    public String description { get; set; }

    [DefaultValue(true)]
    [Display(Name = "Active?")]
    public bool active { get; set; }

    [Display(Name = "Image Name")]
    public String imageName { get; set; }

    [Display(Name = "PDF Name")]
    public String PDFName { get; set; }

    [Display(Name = "Category(s)")]
    public virtual ICollection<CategoryModel> ProductCategories { get; set; }

    public int[] SelectedCategories { get; set; }

    public IEnumerable<SelectListItem> CategorySelectList { get; set; }

    //public ICollection<CategoryModel> CategoryList { get; set; }

    public virtual BrochureModel Brochure { get; set; }

    public IEnumerable<SelectListItem> BrochureList { get; set; }

    [Display(Name = "Category(s)")]
    public String CategoryList { get; set; }

    public static IEnumerable<SelectListItem> getCategories(int id = 0)
    {
        using (var db = new ProductContext())
        {
            List<SelectListItem> list = new List<SelectListItem>();
            var categories = db.Categories.ToList();
            foreach (var cat in categories)
            {
                SelectListItem sli = new SelectListItem { Value = cat.ID.ToString(), Text = cat.categoryName };

                //if (id > 0 && cat.ID == id)
                //{
                //    sli.Selected = true;
                //}
                list.Add(sli);
            }
            return list;
        }

    }

    public ProductModel()
    {
        active = true;
    }

}

还有我的类别模型:

public class CategoryModel
{
    public int ID { get; set; }

    [Required(ErrorMessage = "Required")]
    [Display(Name = "Category Name")]
    [MaxLength(50)]
    public String categoryName { get; set; }

    [MaxLength(50)]
    public String categoryDBName { get; set; }

    [DefaultValue(true)]
    [Display(Name = "Active?")]
    public bool isActive { get; set; }

    //public virtual ICollection<ProductCategory> ProductCategories { get; set; }

    public virtual ICollection<ProductModel> Products { get; set; }


}

这是我的产品上下文:

public class ProductContext : DbContext
{

    public ProductContext()
        : base("DefaultConnection")
    {
        Database.SetInitializer<ProductContext>(new CreateDatabaseIfNotExists<ProductContext>());
    }

    public DbSet<CategoryModel> Categories { get; set; }
    public DbSet<ProductModel> Products { get; set; }
    public DbSet<BrochureModel> Brochures { get; set; }


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        //modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        //modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

        modelBuilder.Entity<CategoryModel>().ToTable("Categories");
        modelBuilder.Entity<ProductModel>().ToTable("Products");
        modelBuilder.Entity<BrochureModel>().ToTable("Brochures");

        modelBuilder.Entity<ProductModel>()
        .HasMany(p => p.ProductCategories)
        .WithMany(p => p.Products)
        .Map(m =>
        {
            m.ToTable("ProductCategory");
            m.MapLeftKey("ProductID");
            m.MapRightKey("CategoryID");
        });

        //modelBuilder.Entity<CategoryModel>()
        //.HasMany(c => c.ProductCategories)
        //.WithRequired()
        //.HasForeignKey(c => c.CategoryID);

    }

    public System.Data.Entity.DbSet<newBestPlay.Models.RegisterViewModel> RegisterViewModels { get; set; }
}

如果需要其他代码或更多信息,请告诉我。

【问题讨论】:

  • 在添加之前是否从会话变量中为 model.Id 分配了正确的值?
  • model.id 为 0 进入“添加”,插入新产品时为真
  • 那么ID是表的主键吗?如果是这样,表中是否已经存储了具有该 ID 的项目?
  • ID 是主要的,但它是自动递增的,所以每次我添加产品时它都会增加一个。产品已正确添加到 Products 表中。它只是没有正确链接到类别。
  • 您是否先使用代码设置实体?如果是这样,您可以发布您的数据库上下文类吗?

标签: asp.net-mvc entity-framework


【解决方案1】:

您永远不会对您的 SelectedCategories 数组做任何事情。您需要使用它从数据库中提取CategoryModel 实例,然后将它们与产品关联。

context.Categories.Where(c => model.SelectedCategories.Contains(c.ID)).ToList()
    .ForEach(c => model.ProductCategories.Add(c));

...

context.SaveChanges();

更新

请问如何在我的视图中列出每个产品的类别?

这是一个复杂的问题,因为它高度依赖于您想要获得的体验类型。一般来说,对于任何集合,您都需要遍历该集合中的项目,然后为每个项目呈现一些 HTML。你可以通过多种不同的方式做到这一点,这就是为什么我不能给你一个真正的“正确”答案。但是,只是为了给您一个想法,而不是让您完全没有代码,这里有一个非常基本的方法来列出每个类别的名称:

@string.Join(", ", Model.ProductCategories.Select(c => c.categoryName))

【讨论】:

  • 完美运行!请问如何在我的视图中列出每个产品的类别?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多