I’ve checked this question and it seems to be related to what I need, but does not answer it exactly.
I have an entity (Sql Compact using EF Code First via MVC3- if that wasn’t clear from the title) for an “Issue” (generic issue tracking, just for my own education understanding of how MVC3 works). The Issue class has a CreatedBy property (Int reference to a User who Created the Issue) and a CreatedDate property (DateTime). When I use the scaffolded code to update (modified only to prevent some updated date fields from being modified by the user):
if (ModelState.IsValid)
{
issue.LastActivity = (DateTime?)DateTime.Now.Date;
if (issue.ClosedBy != null) issue.ClosedDate = (DateTime?)DateTime.Now.Date;
startingIssue = null;
db.Entry(issue).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
I receive the error mentioned in the linked question (conversion of a datetime2 data type to a datetime data type etc., etc.,)
When I step through the code, it appears my CreatedBy and CreatedDate properties are not contained in the instance of issue that the controller is passing around. When I try to fix that by grabbing another copy of the issue from the db, and updating those to values:
var startingIssue = db.Issues.Find(issue.IssueId);
if (ModelState.IsValid)
{
if (issue.CreatedBy != startingIssue.CreatedBy) issue.CreatedBy = startingIssue.CreatedBy;
if (issue.CreatedDate != startingIssue.CreatedDate) issue.CreatedDate = startingIssue.CreatedDate;
issue.LastActivity = (DateTime?)DateTime.Now.Date;
if (issue.ClosedBy != null) issue.ClosedDate = (DateTime?)DateTime.Now.Date;
startingIssue = null;
db.Entry(issue).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
I get the concurrency violation: An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
So, how do I get EF to see the date which is already set in the DB (so it doesn’t try to update the CreatedDate to 1/1/0001) without violating concurrency?
Edit
Okay… I found it. I was, apparently, looking for @Html.HiddenFor(model => model.[property]) and adding the editor to the view anyway. That seems a little silly and round-about to me, but it does work without having to add custom code to detach one object and substitute an updated one.
The short answer is that you’ve already loaded the entity into the context with the
Findand you cannot later attach another one.You are left with two options:
I’ll share code for the first option. First, add a
Detachmethod to yourDbContextimplementation:Then call
Detachinstead of setting the variable tonull