ASP.NET MVC 3一对多表单

iur*_*ona 5 one-to-many ef-code-first entity-framework-4.1 asp.net-mvc-3

我有使用Entity Framework Code First映射的这些类:

public class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
    //... additional properties
    [Required]
    public virtual ICollection<Address> Addresses { get; set; }
}
public class Address
{
    public int AddressId { get; set; }
    public string Street { get; set; }
    //... additional properties

    public int PersonId { get; set; }
    public virtual Person Person { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

因此,使用ASP.NET MVC 3,如何在一个表单中执行人员编辑视图以填充地址中的所有人员属性?

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Person</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Adresses.FirstOrDefault().Street)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Adresses.FirstOrDefault().Street)
            @Html.ValidationMessageFor(model => model.Adresses.FirstOrDefault().Street)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}
Run Code Online (Sandbox Code Playgroud)

这可以很好地显示来自数据库的Street输入,但是当我进行提交时,Street不会改变.

[HttpPost]
public ActionResult Edit(int id, FormCollection formCollection)
{
    Person person = unityOfWork.PersonRepository.GetById(id);

    UpdateModel<Person>(person);

    if (ModelState.IsValid)
    {
        unityOfWork.PersonRepository.Update(person);
        unityOfWork.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(person);
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*gan 3

由于模型绑定器必须修复集合的方式,它会因为相关 ID 不存在而陷入困境。

最好为此屏幕创建一个 ViewModel 并在它和底层域模型之间进行转换。

如果您提供编辑所有地址的工具,我会使用Steve Sanderson 的 BeginCollectionItem helper。但由于您只编辑单个地址,因此具有 Person 属性和单独的Address 属性的新 ViewModel 类会更容易,或者使用包含与此视图相关的 Person 和 Address 属性的类。

我是关注点分离的大力支持者。您的应用程序中逻辑上存在三个模型;实体模型描述数据库中数据存储的实现,视图模型描述 UI 中数据表示的实现,域模型是应用程序中数据的逻辑表示。正如您在这里所做的那样,为每个目的使用相同的模型是很诱人的。但是,一旦您的需求变得不平凡,它就会成为一种负担,因此您最好创建最适合您需要的类。