Please don't mark it as duplicate since i have already gone through similar questions here ,here and here but didn't solve the issue.
Full error message quoted ,
This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
I have 2 related tables Enquiry and EnquiryLineItem , adding/editing dynamically. The edit get method populates and displays all the values bound including the EnquiryLineItems . Using viewmodel and partial views for showing both the related tables . Error occurs when Edit post method.
Models:
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; }
}
Controller method :
[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);
}
Context :
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();
}
In Edit view there is a partial view for adding/editing/deleting LineItems in the Enquiry View itself. So the EnquiryModel Editing will have LineItems which can be edited too or even added/deleted .
Note :
If I add db.Set<Enquiry>().AddOrUpdate(enquiry);
then its adding Enquiry and LineItems as new insert instead of edit.
using MVC 5 and EF6 Codefirst approach. Appreciate some help on this. Thanks in advance.