2

I would really appreciate some insight on this: The following code

        [HttpPost]
    public ActionResult Edit(BeamCollection beamcollection)
    {
        if (ModelState.IsValid)
        {
            beamcollection.BeamMaterial = db.Types.Find(Convert.ToInt32(Request.Form.Get("BeamMaterial_ID")));
            db.Entry(beamcollection).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Details", "Bridge");
        }
        return View(beamcollection);
    }

When I attempt to modify a BeamCollection record, all changes are reflected and saved to the DB except for the beamcollection.BeamMaterial which takes the selected value from a DropDownList. When I debug, I can see that the selected value is being assigned to beamcollection.BeamMaterial!

By the way, this field is defined as follows

public virtual AllTypes BeamMaterial { get; set; }

So it reflects a one to many relationship with AllTypes, but it is a unidirectional relationship.

What is kind of strange (to me), is the the same technique is used for the Create action and it perfectly works:

    public ActionResult Create(BeamCollection beamcollection)
    {
        if (ModelState.IsValid)
        {
            beamcollection.BridgeInfo = db.Bridges.Find(bridgeID);
            beamcollection.BeamMaterial = db.Types.Find(Convert.ToInt32(Request.Form.Get("BeamMaterial_ID")));
            db.BeamCollections.Add(beamcollection);
            db.SaveChanges();
            return RedirectToAction("Details", "Bridge");
        }
        return View(beamcollection);
    }

Why is this happening and how to make it work, Please help.

Musab
  • 21
  • 3

2 Answers2

0

try to use:

db.attach(beamcollection.GetType().Name,beamcollection);
db.ObjectStateManager.ChangeObjectState(beamcollection, EntityState.Modified);
db.SaveChanges();
Fabrice Mainguené
  • 466
  • 1
  • 5
  • 17
  • Thanks Fabric, I think your suggestion works for EF4 but not EF5. I checked this [http://stackoverflow.com/questions/7113434/where-is-context-entry] that mentions these differences. I guess what I am trying to say is that my current code does what you suggested. – Musab Apr 09 '13 at 12:15
  • look at this post too: http://stackoverflow.com/questions/13931714/mvc-4-ef-5-savechanges-does-not-update-database. – Fabrice Mainguené Apr 09 '13 at 19:54
0

Thanks to Fabrice's tip I managed to find the correct way, Here is the code:

            var currentBeamCollection = db.BeamCollections.Find(beamcollection.ID);
            db.Entry(currentBeamCollection).CurrentValues.SetValues(beamcollection);
            currentBeamCollection.BeamMaterial = beamcollection.BeamMaterial;
            db.SaveChanges();

The logic is as follows: get the original record, update all fields (except for the navigation properties, read below), update the navigation property, finally save.

When I tried to do the following

db.Entry(currentBeamCollection).CurrentValues.SetValues(beamcollection.BeamMaterial);

The system failed with an exception that complains about setting the ID property. I also read that CurrentValues.SetValues() doesn't update navigation properties, and I noticed that the BeamMaterial property was not being updated, so I needed to update it manually.

Thanks Fabrice.

Musab
  • 21
  • 3