更正1对多关系的相关字段的正确方法

时间:2012-09-21 06:14:54

标签: asp.net-mvc entity-framework razor

发行人具有相关字段KeyEntity。我的代码有效,但我认为除了从数据库加载实体之外,必须有更好的方法来更新相关字段。 ViewModeling和模板应该有问题......提前谢谢。

OpViewModel

public class OpViewModel
{   
    public Connect.Models.Issuer Issuer { get; set; }
    public IEnumerable<SelectListItem> KeyEntities { get; set; }

    public OpViewModel() { } 
    public OpViewModel(Connect.Models.Issuer issuer, 
                        IEnumerable<Jose.Models.KeyEntity> key_entities)
    {   
        this.Issuer = issuer;
        this.KeyEntities = key_entities.Select(k =>
                        new SelectListItem()
                        {   
                            Selected = (k.Id == issuer.KeyEntity.Id),
                            Text = k.Id.ToString(),
                            Value = k.Id.ToString()
                        }); 
    }   
}   

OP / Edit.chtml(剃刀)

@model AdConnect.Models.OpViewModel
@using (Html.BeginForm()) {

    <div class="editor-field">
        @Html.DropDownListFor(model => model.Issuer.KeyEntity.Id,
                                Model.KeyEntities)
    </div>

}   

OpController

    [HttpPost]
    public ActionResult Edit(Models.OpViewModel obj)
    {   
        if (ModelState.IsValid)
        { 
            //  This works for most data fields of Issuer, but KeyEntity's Id 
            //  (dbo.Issuers.KeyEntity_Id) is not updated.
            //
            //  ctx.Entry(obj.Issuer).State = System.Data.EntityState.Modified

            //  So load Issuer and KeyEntity from the database and update.

            var issuer = ctx.Issuers.Find(obj.Issuer.Id);
            if (obj.Issuer.KeyEntity != null)
            {   
                 issuer.KeyEntity =
                    ctx.KeyEntities.Find(obj.Issuer.KeyEntity.Id);
            }   
            ctx.Entry(issuer).CurrentValues.SetValues(obj.Issuer);

            ctx.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(obj);
    }

1 个答案:

答案 0 :(得分:0)

我认为你对导航属性的工作原理有所了解。 EF可以自动填充它们,因此您不会在对象的构造函数中执行它。

阅读有关导航属性here的文章。

另外,就控制器更新代码而言,更新的正常路径是:加载,修改,保存。

var issuer = ctx.Issuers.Include(i=>i.KeyEntity).SingleOrDefault(i=>i.Id == obj.Issuer.Id);
issuer.Whatever = obj.Issuer.Whatever; //note prehaps you want something like CopyMatchinProperties here
ctx.SaveChanges();