请不要将其标记为重复,因为我已经完成了类似的问题here,here和here,但没有解决问题。
引用完整的错误消息,
如果图中的任何实体具有冲突的键值,则使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图表,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。
我有2个相关的表Inquiry和EnquiryLineItem,动态添加/编辑。 edit get方法填充并显示绑定的所有值,包括EnquiryLineItems。使用viewmodel和partial视图显示相关表。编辑帖子方法时出错。
模特:
public class Enquiry : BaseEntity
{
public Enquiry()
{
EnquiryLineItems = new List<EnquiryLineItem>();
}
public int ID { get; set; }
public DateTime? PreparedDate { get; set; }
[StringLength(12)]
public string EnquiryNumber { get; set; }
public DateTime? ClosingDate { get; set; }
public int DivisionID { get; set; }
public Division Division { get; set; }
public int ClientID { get; set; }
public Client Client { get; set; }
public virtual ICollection< EnquiryLineItem> EnquiryLineItems { get; set; }
public DateTime? RFQSentDate { get; set; }
}
public class EnquiryLineItem : BaseEntity
{
public int ID { get; set; }
[StringLength(80)]
public string ItemDesc { get; set; }
[Range(1, int.MaxValue, ErrorMessage = "Please enter valid Quantity")]
public int Quantity { get; set; }
public int EnquiryID { get; set; }
public Enquiry Enquiry { get; set; }
public int? ManufacturerID { get; set; }
public Manufacturer Manufacturer { get; set; }
}
控制器方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit( EnquiryVM enquiryVM)
{
var ID = enquiryVM.ID;
var enquiry = new Enquiry();
enquiry.EnquiryNumber = enquiryVM.EnquiryNumber;
enquiry.ClosingDate = enquiryVM.ClosingDate;
enquiry.RFQSentDate = enquiryVM.RFQSentDate;
enquiry.ClientID = enquiryVM.ClientID;
enquiry.DivisionID = enquiryVM.DivisionID;
if (ModelState.IsValid)
{
foreach (var lineItemVm in enquiryVM.LineItems)
{
EnquiryLineItem enquiryLineItem = new EnquiryLineItem();
enquiryLineItem.ItemDesc = lineItemVm.ItemDesc;
enquiryLineItem.Quantity = lineItemVm.Quantity;
enquiryLineItem.ManufacturerID = lineItemVm.ManufacturerId;
enquiry.EnquiryLineItems.Add(enquiryLineItem);
}
db.Entry(enquiry).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
//ConfigureViewModel();
return View(enquiryVM);
}
背景:
public override int SaveChanges()
{
foreach (var entry in ChangeTracker.Entries())
{
var entity = entry.Entity;
if (entry.State == EntityState.Added)
{
entry.Property("AddedDate").CurrentValue = DateTime.Now;
entry.Property("AddedBy").CurrentValue = HttpContext.Current.User.Identity.Name;
entry.Property("AddedById").CurrentValue = HttpContext.Current.User.Identity.GetUserId();
}
else if (entry.State == EntityState.Modified)
{
entry.Property("AddedDate").IsModified = false;
entry.Property("AddedBy").IsModified = false;
entry.Property("AddedById").IsModified = false;
entry.Property("ModifiedDate").CurrentValue = DateTime.Now;
entry.Property("ModifiedBy").CurrentValue = HttpContext.Current.User.Identity.Name;
entry.Property("ModifiedById").CurrentValue = HttpContext.Current.User.Identity.GetUserId();
}
}
return base.SaveChanges();
}
在“编辑”视图中,有一个部分视图,用于在“查询视图”本身中添加/编辑/删除LineItems。所以EnquiryModel Editing将有LineItems,可以编辑,甚至添加/删除。
注意:
如果我添加db.Set<Enquiry>().AddOrUpdate(enquiry);
,则将其添加查询和LineItems作为新插入而不是编辑。
使用MVC 5和EF6 Codefirst方法。 感谢一些帮助。提前致谢。
答案 0 :(得分:1)
您创建新的Enquiry
数据模型并未设置其ID
属性或将其附加到上下文。您应该根据视图模型的ID获取现有数据模型,然后更新其属性然后保存。
将控制器代码更改为
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit( EnquiryVM enquiryVM)
{
if(!ModelState.IsValid)
{
ConfigureViewModel(enquiryVM);
return View(enquiryVM)
}
// Get the data model
var enquiry = db.Enquiries.FirstOrDefault(x => x.ID == enquiryVM.ID.Value);
// update properties of enquiry from the enquiryVM
enquiry.EnquiryNumber = enquiryVM.EnquiryNumber;
enquiry.ClosingDate = enquiryVM.ClosingDate;
....
foreach (var lineItemVm in enquiryVM.LineItems)
{
if (lineItemVm.ID.HasValue)
{
var lineItem = enquiry.LineItems.FirstOrDefault(x => x.ID == lineItemVm.ID.Value);
// update properties of lineItem from lineItemVm (but dont add it to the collection)
lineItem.ItemDesc = lineItemVm.ItemDesc;
lineItem.Quantity = lineItemVm.Quantity;
lineItem.ManufacturerID = lineItemVm.ManufacturerId;
}
else
{
// create a new EnquiryLineItem data model based on lineItemVm and add it to the data models `LineItems` collection
EnquiryLineItem enquiryLineItem = new EnquiryLineItem();
enquiryLineItem.EnquiryID = enquiryVM.ID.Value; // modify this
enquiryLineItem.ItemDesc = lineItemVm.ItemDesc;
enquiryLineItem.Quantity = lineItemVm.Quantity;
enquiryLineItem.ManufacturerID = lineItemVm.ManufacturerId;
enquiry.EnquiryLineItems.Add(enquiryLineItem);
}
db.Entry(enquiry).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}