简体   繁体   English

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

[英]MVC 5 Creation of foreign key entities during primary entity creation

I am utterly new to MVC and asp.net with Entity Framework so I am sure that most of my trouble stems from not knowing the proper terminology for what I am trying to do. 我对使用Entity Framework的MVC和asp.net完全陌生,因此我可以确定,我的大部分麻烦源于不了解我要执行的操作的正确术语。

I have an "Address" database table/ entity that is a street address. 我有一个“地址”数据库表/实体,它是街道地址。 Rather than having the street address fields in every entity that has an associated address, I simply have a foreign key column that points to the correct address in the address table. 我没有在每个具有关联地址的实体中都具有街道地址字段,而是仅拥有一个外键列,该列指向地址表中的正确地址。

For my Location creation view model, I have the following 对于我的位置创建视图模型,我有以下内容

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

}

It is probably worth pointing out that that View model is "hand made" while the address and location member objects are managed by the entity framework 可能值得指出的是,视图模型是“手工制作的”,而地址和位置成员对象是由实体框架管理的

My Create View has all of the location data, and then includes a partial address view which is rendered with Html.Partial("_AddressCreate", Model.Location) 我的创建视图具有所有位置数据,然后包括一个用Html.Partial("_AddressCreate", Model.Location)呈现的部分地址视图。

What currently happens is the LocationCreationViewModel returned in the Create(model) function is LocationCreationViewModel is null, or each of the fields is null. 当前发生的情况是在Create(model)函数中返回的LocationCreationViewModel为LocationCreationViewModel为null,或者每个字段为null。 In any event, none of the data from the view is populated in the view model. 无论如何,视图模型中不会填充视图中的任何数据。

What I want to happen is that I get back the 2 addresses, add them to the address table in the database, then add my order to the order database with FK address fields pointing to the 2 newly created addresses. 我要发生的是,我取回2个地址,将它们添加到数据库中的地址表中,然后将我的订单添加到具有2个新创建的地址的FK地址字段的订单数据库中。

I am using MVC5 and EF6 in visual studio 2017 我在Visual Studio 2017中使用MVC5和EF6

Create.cshtml 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 _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 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);
        }

The autobinder failed to bind form data because of the field name Location in the View Model. 由于视图模型中的字段名称Location ,自动绑定器无法绑定表单数据。 I assume that this is due to Location being part of the page route. 我认为这是由于“ Location是页面路由的一部分。 IE for the LocationController, the route would be /Location/Create IE的LocationController,路由为/Location/Create

In any event, renaming LocationCreationViewModel::Location to LocationCreationViewModel::Locus fixed everything. 无论如何,将LocationCreationViewModel::Location重命名为LocationCreationViewModel::Locus修复所有问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM