两个模型之间的一对一关系?

时间:2013-02-17 02:19:51

标签: c# asp.net asp.net-mvc-3 entity-framework asp.net-mvc-4

我有以下Model类(我首先使用EF代码生成表)。

public class MyClass
{
    ....
    [Required, ForeignKey("Address")]
    public int Address1Id { get; set; }
    virtual public Address Address1 { get; set; }
    [Required, ForeignKey("Address")]
    public int Address12d { get; set; }
    virtual public Address Address2 { get; set; }
    [Required, ForeignKey("Address")]
    public int Address3Id { get; set; }
    virtual public Address Address3 { get; set; }
    ....
}
public class Address { .... }

我希望MyClass的创建视图显示所有地址字段,并且在保存MyClass时,地址将首先保存在表格地址中。但是脚手架为地址生成了一个DropDownList框。如何修改代码以使其像这些地址字段一样直接在类MyClass中编码,并让控制器将表AddressAddressID中的地址保存在表{{1}中}}?

MyClass

更新 我尝试创建以下ViewModel,但脚手架抱怨没有在类中定义键。

    <div class="editor-label">
        @Html.LabelFor(model => model.Address1Id, "Address")
    </div>
    <div class="editor-field">
        @Html.DropDownList("Address1Id", String.Empty)
        @Html.ValidationMessageFor(model => model.Address1Id)
    </div>

2 个答案:

答案 0 :(得分:1)

您的外键属性不正确:

[Required, ForeignKey("Address1")]
...
[Required, ForeignKey("Address2")]
...
[Required, ForeignKey("Address3")]
...

(并且Address12d我猜错了)

答案 1 :(得分:1)

听起来你在询问如何在MVC中为编辑/创建视图展平模型。您不想创建Person,然后创建一个Address,而是在一个屏幕上创建它。如果这就是你要问的,是的,你可以做到!事实上,做你想做的事就像将你的创建视图改为:

一样简单
<h3>Address 1</h3>
@Html.EditorFor(x => x.Address1)
<h3>Address 2</h3>
@Html.EditorFor(x => x.Address2)
...etc

默认情况下,MVC非常聪明,可以猜出Address的“编辑器”应该是什么样子。字符串的文本字段,bool的复选框等。如果[HttpPost]控制器看起来像这样:

[HttpPost]
public ActionResult Create(Person person)
{
    if (ModelState.IsValid)
    {
        var context = new AppDbContext();
        context.People.Add(person);
        context.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(personViewModel);
}

如果你在调试器中检查person,你应该看到Address属性都已填入.Yup,MVC ModelBinder非常聪明!你不应该做任何其他事情。

注意:当您在项目中取得进展并且数据模型不可避免地变得更加复杂时,您可能会遇到从控制器到视图来回传递模型对象的问题。我强烈建议遵循使用ViewModel的模式,ViewModel是表示视图的“模型”的普通对象,也就是说,它应该捆绑进出客户端的所有数据。这将允许您展平数据模型并仅包含您实际需要的字段。您可能不需要将此模式用于此特定示例,但将来会有所帮助。

希望这有帮助!