简体   繁体   中英

Entity framework - Relation not updating

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);
        }
    }

您必须在修改实体后调用db.SaveChanges()

I managed to find the issue. This was not an easy one.

I noticed that most of my relations created a Scalar value to the 'child' entity. (Eg Category shoud have automatically received a DepartmentID scalar value). But this was not the case.

Here's the issue: if you create the association in EF, you get a window asking you to choose which two entities you want to associate. The child (Category, one) needs to be in the right field, while the parent (Department, many) needs to be on the left. The menu allows you to place them either side, there is nothing preventing you from doing this. But only if you enter the data one <-> many you will get the scalar value added. Not when you put it like many <-> one> even though that should be literally the same thing.

Am I right in stating that this is a bug?

My original snippet, which only does the .Attach() and EntityState.Modified now works as expected.

I can only mark this answer as correct in 2 days, but you can consider this question as closed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM