如何在MVC5中编辑嵌套集合?

时间:2015-07-17 16:05:21

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

我有一个EF模型,其中包含“键”和“值”。 value-table包含密钥的FK。在EF模型中,它看起来像这样:

public partial class dict_key
{
    public dict_key()
    {
        this.dict_value = new HashSet<dict_value>();
    }
    public int id { get; set; }
    public string name { get; set; }
    ...
    public virtual ICollection<dict_value> dict_value { get; set; } //dict_value contains a string "value"
}

我的控制器正在传递信息进行编辑,如下所示:

// GET: Keys/Texts/5
[Authorize]
public async Task<ActionResult> Texts(int? id)
{
    var key = await db.dict_key
        .Include(x => x.dict_value)
        .Where(x => x.id.Equals(id.Value))
        .FirstOrDefaultAsync();
    return View(key);
    // Debugging 'key' shows that dict_value has 3 correct values.
}

这会传递给我的View,它显示了dict_value的正确性:

@model Dict.Models.dict_key
@using (Html.BeginForm())
{
    <div>Key: @Model.name </div>
    <table class="table">
        <tr>
            <th>Language</th>
            <th>Text</th>
        </tr>
        @for (var i = 0; i < Model.dict_value.Count(); i++)
        {
            <tr>
                <td> @Model.dict_value.ElementAt(i).dict_lang.name_en </td>
                <td> @Html.EditorFor(x => x.dict_value.ElementAt(i).value) </td>
            </tr>
        }
        <div class="form-group">
            <input type="submit" value="Save" />
        </div>
    </table>
}

将我的更改提交回控制器......

[HttpPost]
public async Task<ActionResult> Texts(dict_key dict_key)
{
    if (ModelState.IsValid)
    {
        //Also tried: db.Entry(dict_key).State = EntityState.Modified;
        db.Entry(dict_key.dict_value).State = EntityState.Modified;
        await db.SaveChangesAsync();
        return RedirectToAction("Texts");
    }
    return View(dict_key);
}

..然后我的“dict_key”与我传递给编辑视图的对象完全不同。传递的对象包含dict_value的集合,“返回”和编辑的对象返回正确的密钥对象,但带有空的dict_value集合。

我尽量避免使用用户定义的模型或viewbag来手动完成所有这些操作。什么是最佳实践解决方案?

1 个答案:

答案 0 :(得分:1)

Collection.ElementAt在Razor中没有生成正确的字段名称。你需要一个List。在这里,您应该直接使用视图模型而不是实体,只需将dict_value集合设置为List<dict_value>

或者,您可以为dict_value创建一个编辑器模板,然后在您的视图中执行:

@Html.EditorFor(m => m.dict_value)

dict_value哪里有你的整个收藏。 Razor将为集合的每个成员呈现编辑器模板的实例,并正确地索引所有内容。