I am having issues with updating the relation between two entities when editing one of them. Please note that I am using Entity Framework 4.0.
Very basically, a Category
needs to belong to a Department
(one Department
to many Categories
).
I implemented the following directly into the Category
model:
public void Save()
{
using (var db = new MyDatabase())
{
if (this.id > 0)
{
db.Categories.Attach(this);
db.ObjectStateManager.ChangeObjectState(this, EntityState.Modified);
}
else
{
db.Categories.AddObject(this);
}
db.SaveChanges();
}
}
public int DepartmentID
{
get
{
if (this.DepartmentReference.EntityKey == null) return 0;
else return (int)this.DepartmentReference
.EntityKey.EntityKeyValues[0].Value;
}
set
{
this.DepartmentReference.EntityKey
= new EntityKey("MyDatabase.Departments", "Id", value);
}
}
Creating an object works without issue, it's only when I try to save an edited item that the issue occurs (so the issue lies within the if (this.id > 0)
block).
I am aware that EntityState.Modified
only applies to scalar values. The above snippet is a slightly older version. I have already tried to fix it in numerous ways, but none of these have solved the problem.
I found numerous solutions on Stackoverflow, but none of them worked. See below for snippets of my previous attempts.
I checked the values in debug, the current item's Department
and DepartmentID
fields correctly hold the changed value. Before the attaching, after the attaching, all the way through. But Entity Framework is ignoring these changes, while still correctly doing the scalar value adjustments.
What am I missing? If anyone could point me in the right direction?
The things I tried include:
//First try
if (this.id > 0)
{
var department = db.Departments.Single(x => x.Id == this.DepartmentID);
db.Categories.Attach(this);
this.Department = department;
db.ObjectStateManager.ChangeObjectState(this, EntityState.Modified);
}
//Second try
if (this.id > 0)
{
db.Categories.Attach(this);
db.Departments.Attach(this.Department);
db.ObjectStateManager.ChangeObjectState(this, EntityState.Modified);
}
//Third try
if (this.id > 0)
{
var department = db.Departments.Single(x => x.Id == this.DepartmentID);
db.Categories.Attach(this);
this.DepartmentID = department.Id;
db.ObjectStateManager.ChangeObjectState(this, EntityState.Modified);
}
//Fourth try
if (this.id > 0)
{
var departmentID = this.DepartmentID;
db.Categories.Attach(this);
this.Department = db.Departments.Single(x => x.Id == departmentID);
db.ObjectStateManager.ChangeObjectState(this, EntityState.Modified);
}
Update
As requested, here's how the .Save()
method is being called. Please note that the actual web form has been build using TextBoxFor()
etc. so the modelbinding is okay. This exact same method is also used for the creation of the categories, which does work as intended.
public JsonResult SaveCategory(Category category)
{
try
{
category.Save();
return Json(category.toJson(), JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json("ERROR", JsonRequestBehavior.AllowGet);
}
}