1

我有以下操作方法:-

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

但如果引发 DbUpdateConcurrncy 异常,我将在databaseValues.DataCenter.Name & databaseValues.Zone.Name. 似乎我无法从Getdatabase().Toobject.

知道如何解决这个问题吗?请记住,这两个导航值已经在数据库中具有值。

4

1 回答 1

0

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].Find(idOfReferencedElement);
}
于 2015-04-22T15:57:09.583 回答