0

I have the folloiwng Action Methods:-

 [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Rack rack)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    repository.InsertOrUpdateRack(rack);
                    repository.Save();
                    return RedirectToAction("Index");
                }

            }
            catch (DbUpdateConcurrencyException ex)
            {
                var entry = ex.Entries.Single();
                var databaseValues = (Rack)entry.GetDatabaseValues().ToObject();
                var clientValues = (Rack)entry.Entity;


                if (databaseValues.RU != clientValues.RU)
                    ModelState.AddModelError("RU", "Current value: "
                        + databaseValues.RU);
                if (databaseValues.DataCenterID != clientValues.DataCenterID)
                    ModelState.AddModelError("DataCenterID", "Current value: "
                        + databaseValues.DataCenter.Name);
                if (databaseValues.ZoneID != clientValues.ZoneID)
                    ModelState.AddModelError("ZoneID", "Current value: "
                        + databaseValues.Zone.Name);

But if a DbUpdateConcurrncy exception is raised i will get a Null reference exception on databaseValues.DataCenter.Name & databaseValues.Zone.Name. It seems that i can not access the two navigation properties (Datacenter & Rack) from the Getdatabase().Toobject.Any idea how i can solve this issue?

1 Answers1

0

I've also given this answer here but am copying this here for others' convenience as this question came up on the first page of my Google search:

I'm just leaving here for anyone who still stumbles upon this when trying to handle concurrency issues or the like.

The ToObject method currently doesn't populate the navigational properties of the entity form the database when it populates the entity with the latest database values. This is somehow acceptable as the navigational properties may have additions/deletions that should be handled manually. Also bear in mind that the entity is detached

I haven't really been able to find a way to populate those values automatically by the EF. You probably have to use the 'GetValue` method for each property you are interested in and then populate them yourself.

Here is a pseudo-code like solution:

DbEntityEntry entry = context.Entry(yourEntity);
//Gets latest values of entity from the database
var propertyValues = entry.GetDatabaseValues();
//Fills an entity object with database values(except navigational properties)
dynamic newEntity = propertyValues.ToObject();
//Manually loading the needed navigational properties and handling add/removes.
foreach (var prop in propertyValues.PropertyNames)
{
    //either a collection<int> or an int.
    var idOfReferencedElement = propertyValues.GetValue<int>(foreignKeyField);
    //remember to handle add/removes too.
    newEntity.[thePropertyYouKnowExist] = context.[theDBSet].Local.Find(idOfReferencedElement);
}
Community
  • 1
  • 1
Farhad Alizadeh Noori
  • 2,136
  • 15
  • 22