温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c# - MVC 5
c# entity-framework asp.net-mvc-5

c# - MVC 5

发布于 2020-03-27 11:35:01

我对MVC 5相对较新,并且在弄清楚如何更新关系表时遇到问题。我首先使用EF代码。我已经花了很多时间来寻找解决方案,但是我找不到与我的代码相关的任何东西,这就是为什么我除了在这里问之外别无选择,所以我对此表示歉意。

I am including the relational table in my Razor view which works very well. But when I want to update the table it simply doesn't update even though I get no errors with my current code. I've also tried adding an extra Bind[(Include = "Id,FirstName,LastName")], but this used the Booking FirstName and LastName. I am unsure if my methods are the "proper" ones. My logic tells me that I need to fetch the data from the view and retrieve them in the controller but I don't know how if I can't use Bind or the db.Entry(item).State = EntityState.Modified?

Booking.cs

namespace Ventures.Innovation.InteractiveModel.Context
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.Spatial;

    public partial class Bookings
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]

        public Bookings()
        {
            AttendingPeople = new HashSet<AttendingPeople>();
        }

        public int Id { get; set; }

        [Required]
        [StringLength(128)]
        public string AspNetUserFk { get; set; }

        [Required]
        public DateTime Date { get; set; }

        [Required]
        [StringLength(100)]
        public string FirstName { get; set; }

        [Required]
        [StringLength(50)]
        public string LastName { get; set; }

        public virtual AspNetUsers AspNetUsers { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]

        public virtual ICollection<AttendingPeople> AttendingPeople { get; set; }
    }
}

AttendingPeople.cs

namespace Ventures.Innovation.InteractiveModel.Context
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.Spatial;

    public partial class AttendingPeople
    {
        public int Id { get; set; }
        public int BookingId { get; set; }

        [Required]
        [StringLength(100)]
        public string FirstName { get; set; }

        [Required]
        [StringLength(50)]
        public string LastName { get; set; }

        public virtual Bookings Bookings { get; set; }
    }
}

Controller

// GET: AdminHome/Edit/5
public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    Bookings bookings = db.Bookings.Find(id);
    if (bookings == null)
    {
        return HttpNotFound();
    }

    ViewBag.AspNetUserFk = new SelectList(db.AspNetUsers, "Id", "Email", bookings.AspNetUserFk);

    var attendingPeople = db.AttendingPeople.Where(a => a.BookingId == id).ToList();
    bookings.AttendingPeople = attendingPeople;

    return View(bookings);
}

// POST: AdminHome/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,AspNetUserFk,Date,FirstName,LastName")] Bookings bookings)
{
    if (ModelState.IsValid)
    {
        db.Entry(bookings).State = EntityState.Modified;
        db.SaveChanges();

        var editedAttendingPeople = db.AttendingPeople.Where(a => a.BookingId == bookings.Id).ToList();

        foreach (var item in editedAttendingPeople)
        {
            db.Entry(item).State = EntityState.Modified;
        }

        db.SaveChanges();

        return RedirectToAction("Index");
    }

    ViewBag.AspNetUserFk = new SelectList(db.AspNetUsers, "Id", "Email", bookings.AspNetUserFk);

    return View(bookings);
}

View

@model Ventures.Innovation.InteractiveModel.Context.Bookings

@{
    ViewBag.Title = "Edit booking";
}

<h2>Edit booking</h2>
<hr />

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

<div class="form-horizontal">
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.HiddenFor(model => model.Id)
</div>

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

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

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

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

    @if (Model.AttendingPeople.Count > 0)
    {
        @Html.Label("Attending people")

        foreach (var attendingPeople in Model.AttendingPeople)
        {
            <div class="form-group">
                <div class="col-md-10">
                    @Html.LabelFor(modelItem => attendingPeople.FirstName, htmlAttributes: new { @class = "control-label col-md-5", @style = "padding-left: 0;" })
                    @Html.LabelFor(modelItem => attendingPeople.LastName, htmlAttributes: new { @class = "control-label col-md-5", @style = "padding-left: 0;" })
                </div>
                <div class="col-md-10">
                    @Html.EditorFor(modelItem => attendingPeople.FirstName, new { htmlAttributes = new { @class = "form-control col-md-5", @style = "display: initial;" } })
                    @Html.EditorFor(modelItem => attendingPeople.LastName, new { htmlAttributes = new { @class = "form-control col-md-5", @style = "display: initial;" } })
                </div>
            </div>
        }
    }

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

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

I want to save the updated data to AttendingPeople table in the database but nothing happens.

查看更多

查看更多

提问者
Ghost
被浏览
92
Ghost 2019-07-04 01:10

Thanks to JARRRRG for helping me out here. :)

为了解决这个问题,我需要确保我的命名完全相同。显然,这就是它从视图到控制器的查找/绑定方式。另外,我还需要确保使用了for循环,以便集合可以区分对象。

这是我的更新视图:

@if (Model.AttendingPeople.Count > 0)
{
    @Html.Label("Attending people")
    var attendingPeople = Model.AttendingPeople.ToArray();

    foreach (int i = 0; i < attendingPeople.Length; i++)
    {
        @Html.HiddenFor(modelItem => attendingPeople[i].Id)
        <div class="form-group">
            <div class="col-md-10">
                @Html.LabelFor(modelItem => attendingPeople[i].FirstName, htmlAttributes: new { @class = "control-label col-md-5", @style = "padding-left: 0;" })
                @Html.LabelFor(modelItem => attendingPeople[i].LastName, htmlAttributes: new { @class = "control-label col-md-5", @style = "padding-left: 0;" })
            </div>
            <div class="col-md-10">
                @Html.EditorFor(modelItem => attendingPeople[i].FirstName, new { htmlAttributes = new { @class = "form-control col-md-5", @style = "display: initial;" } })
                @Html.EditorFor(modelItem => attendingPeople[i].LastName, new { htmlAttributes = new { @class = "form-control col-md-5", @style = "display: initial;" } })
            </div>
        </div>
    }
}

这是我的新编辑:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,AspNetUserFk,Date,FirstName,LastName")] Bookings bookings, ICollection<AttendingPeople> attendingPeople)
{
    if (ModelState.IsValid)
    {
        db.Entry(bookings).State = EntityState.Modified;
        db.SaveChanges();

        foreach (var item in attendingPeople)
        {
            item.BookingId = bookings.Id;
            db.Entry(item).State = EntityState.Modified;
        }

        db.SaveChanges();

        return RedirectToAction("Index");
    }

    ViewBag.AspNetUserFk = new SelectList(db.AspNetUsers, "Id", "Email", bookings.AspNetUserFk);

    bookings = db.Bookings.Include(at => at.AttendingPeople).SingleOrDefault(b => b.Id == bookings.Id)

    return View(bookings);
}