C# 实体框架-插入具有多对多关系的记录

C# 实体框架-插入具有多对多关系的记录,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,当我的实体之间有一对多关系时,我的应用程序运行得很好,但现在我尝试将其切换到多对多,我正在努力让它正确插入。我想我的模型中可能有一些不太正确的地方 现在,当我在控制器中运行context.saveChanges()时,由于以下错误,它失败:在97毫秒内失败,错误为:INSERT语句与外键约束“FK_dbo.Products_dbo.Categories_CategoryID”冲突。冲突发生在数据库“database”、表“dbo.Categories”、列“ID”中。语句已终止。我查看了查询。我

当我的实体之间有一对多关系时,我的应用程序运行得很好,但现在我尝试将其切换到多对多,我正在努力让它正确插入。我想我的模型中可能有一些不太正确的地方

现在,当我在控制器中运行context.saveChanges()时,由于以下错误,它失败:
在97毫秒内失败,错误为:INSERT语句与外键约束“FK_dbo.Products_dbo.Categories_CategoryID”冲突。冲突发生在数据库“database”、表“dbo.Categories”、列“ID”中。语句已终止。
我查看了查询。我有3个id为1、2和3的现有类别。现在在我的查询中,CategoryID是0,但我的IEnumerable CategoryID中有1和2,这正是我想要的。如何将其输入类别1和类别2的产品

类别模型:

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 ICollection<ProductModel> ProductList { get; set; }

}

编辑:我忘了提到我有第三个名为ProductCategory的表,它有ProductID和CategoryID,但我没有该表的模型。

创建项并调用
SaveChanges()
的控制器中的代码在哪里?很可能EF认为您正在尝试添加新项目,而不是更新现有项目,但是如果没有看到您正在使用的代码,就无法知道。您可以发布控制器或其他内容,以便我们知道您在这里尝试执行的操作吗?很可能您需要将ID放入视图中的隐藏表单字段中,这样它就不会在HttpPost方法中返回为零,即默认值(int)。你需要第三个模型将两者联系在一起,否则你会过得很糟糕。但是,我有点困惑,为什么产品和类别之间有一对多和多对多的关系。
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; }

    [ForeignKey("Category")]
    public int CategoryID { get; set; }

    public IEnumerable<int> CategoryIDs { get; set; }

    public virtual CategoryModel Category { 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; }

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

}
// POST
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult EditProduct([Bind(Include = "ID,itemNumber,product,description,active,PDFName,imageName,CategoryIDs")] 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.CategoryID;
                    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);
    }