inserting record with many to many relationship
My application was working fine when I had a one to many relationship between my entities but now I have tried to switch it to a many to many and I'm struggling on how to get it to correctly insert. I think I probably have something not quite right in my models.
Now when I run a context.saveChanges() in my controller, it is failing because of this error: Failed in 97 ms with error: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Products_dbo.Categories_CategoryID". The conflict occurred in database "database", table "dbo.Categories", column 'ID'. The statement has been terminated.
Failed in 97 ms with error: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Products_dbo.Categories_CategoryID". The conflict occurred in database "database", table "dbo.Categories", column 'ID'. The statement has been terminated.
I took a look at the query. I have 3 existing categories with id's of 1, 2, and 3. Now in my query the CategoryID is 0 but my IEnumerable CategoryIDs has a 1 and 2 in it which is what I want. How do I proceed to get this to enter the product for both category 1 and 2?
Category Model:
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; }
}
Product 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; }
[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;
}
}
And here is the method in the controller that is saving the changes:
// 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);
}
Edit: I forgot to mention that I do have a third table called ProductCategory that has a ProductID and a CategoryID but I do not have a model for that table.
链接地址: http://www.djcxy.com/p/33490.html上一篇: 实体框架核心1.1和迁移
下一篇: 插入与多对多关系的记录