MVC 5在主实体创建期间创建外键实体

时间:2019-03-18 18:25:42

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

我对使用Entity Framework的MVC和asp.net完全陌生,因此我可以确定,我的大部分麻烦源于对所尝试操作的术语不了解。

我有一个“地址”数据库表/实体,它是街道地址。而不是在每个具有关联地址的实体中都具有街道地址字段,我只是拥有一个外键列,该列指向地址表中的正确地址。

对于我的位置创建视图模型,我有以下内容

public class LocationCreationViewModel
{
    public address Address { get; set; }
    [Key]
    public location Location { get; set; }

}

可能值得指出的是,View模型是“手工制作的”,而地址和位置成员对象是由实体框架管理的。

“我的创建视图”具有所有位置数据,然后包括一个局部地址视图,该视图以 Html.Partial("_AddressCreate", Model.Location)

当前发生的情况是Create(model)函数中返回的LocationCreationViewModel为LocationCreationViewModel为空,或者每个字段为空。无论如何,视图模型中不会填充视图中的任何数据。

我想发生的事情是,我取回2个地址,将它们添加到数据库中的地址表中,然后将我的订单添加到具有2个新创建的地址的FK地址字段的订单数据库中。

我正在Visual Studio 2017中使用MVC5和EF6

Create.cshtml

@model MyWeb.Models.LocationCreationViewModel

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>location</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Location.name, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Location.name, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Location.name, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Location.address, "address", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("address", null, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Location.address, "", new { @class = "text-danger" })
        </div>
    </div>
    @Html.Partial("_AddressPartial", Model.Address)

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

_AddressPartial.cshtml

@model MyWeb.Data.address

    <div class="form-horizontal">
        <h4>address</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.country, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.country, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.country, "", new { @class = "text-danger" })
            </div>
        </div>


        <div class="form-group">
            @Html.LabelFor(model => model.locality, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.locality, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.locality, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.postalCode, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.postalCode, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.postalCode, "", new { @class = "text-danger" })
            </div>
        </div>


    </div>

LocationController :: Create

[MyWebAuthorize(MyWebRole = MyWebRole.Admin)]
        public ActionResult Create()
        {
            ViewBag.address = new SelectList(db.addresses, "id", "country");
            ViewBag.id = new SelectList(db.inventories, "locationID", "locationID");

            LocationCreationViewModel model = new LocationCreationViewModel();
            return View(model);
        }


[HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Create( LocationCreationViewModel location)
        {
            if (ModelState.IsValid)
            {
                db.addresses.Add(location.Address); //null reference exception here
                db.locations.Add(location.Location);

                await db.SaveChangesAsync();
                return RedirectToAction("Index");
            }

            ViewBag.address = new SelectList(db.addresses, "id", "country", location.Location.address);
            ViewBag.id = new SelectList(db.inventories, "locationID", "locationID", location.Location.id);
            return View(location);
        }

1 个答案:

答案 0 :(得分:0)

由于视图模型中的字段名称Location,自动绑定器无法绑定表单数据。我认为这是由于Location是页面路由的一部分。 IE的LocationController,路由为/Location/Create

无论如何,将LocationCreationViewModel::Location重命名为LocationCreationViewModel::Locus可以解决所有问题。