简体   繁体   中英

Edit Multiple Related Tables in a single view

I have four tables with three one to many relationships and I want to edit all these four tables in a single view. Here's the structure of model of these tables :

Model 1 (Base Table):

    public partial class benedet
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public benedet()
        {
            this.bankdets = new HashSet<bankdet>();
            this.damagedets = new HashSet<damagedet>();
            this.imagedets = new HashSet<imagedet>();
        }

        public int id { get; set; }
        [Key]
        public string beneid { get; set; }
        public string name { get; set; }

        //More Properties....

        public virtual ICollection<bankdet> bankdets { get; set; }

        public virtual ICollection<damagedet> damagedets { get; set; }

        public virtual ICollection<imagedet> imagedets { get; set; }
    }

Model 2 (Child Table):

    public partial class bankdet
    {
        public int id { get; set; }
        public string beneid { get; set; }

        //More Properties....

        public virtual benedet benedet { get; set; }
    }

Model 3 (Child Table):

    public partial class damagedet
    {
        public int id { get; set; }
        public string beneid { get; set; }
        public string name { get; set; }

        //More Properties.....

        public virtual benedet benedet { get; set; }
    }

Model 4 (Child Table):

public partial class imagedet
{
    public int id { get; set; }

    public string beneid { get; set; }
    public string url { get; set; }
    public string desc { get; set; }

    public virtual benedet benedet { get; set; }
}

Model 1 has a one-to-many relationship with model 2 ,3 and 4 using the key beneid . I am trying to edit these model's data in a single view but only the base model (table 1) gets modified whereas the child model don't. I have also tried explicitly setting the keys using [ForeignKey("beneid")] attribute but was unsuccessful. Here are my edit methods and view for reference.

        public ActionResult Edit(string id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            benedet benedet = db.benedets.Find(id);
            if (benedet == null)
            {
                return HttpNotFound();
            }
            benedet.imagedets = (from o in db.imagedets where o.beneid == benedet.beneid select o).ToList();
            benedet.bankdets = (from p in db.bankdets where p.beneid == benedet.beneid select p).ToList();
            benedet.damagedets = (from i in db.damagedets where i.beneid == benedet.beneid select i).ToList();
            return View(benedet);
        }

        // POST: BeneficiaryMaster/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(benedet benedet)
        {

            if (ModelState.IsValid)
            {

                db.Entry(benedet).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(benedet);
        }

VIEW:

@model IdentitySample.Models.benedet
@using System.Text;
@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

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

    <div class="form-horizontal">
        <h4>benedet</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.beneid)
        <input type="hidden" id="id" name="id" value="@Model.id" />
        <table class="table table-striped table-bordered table-condensed">
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.name)
                </th>
                <!-- More headers..... -->              


            </tr>
            <tr>
                <td>
                    @Html.EditorFor(modelItem => Model.name, new { htmlAttributes = new { @class = "form-control" } })
                </td>
               <!-- More Data.... -->                   
            </tr>
        </table>
        <h3>Bank Details</h3>
        <table class="table table-striped table-bordered table-condensed">
            <tr>
              <!--Headers-->
            </tr>
            @foreach (var item in Model.bankdets)
            {
                var i = 0;

                <tr>
                   <!--Data-->
                </tr>
                i++;
            }
        </table>




        <h3>Damage Records</h3>
        <table class="table table-striped table-bordered table-condensed">
            <tr>
                <th>
                    Name
                </th>
               <!--Headers -- >
            </tr>
            @foreach (var item in Model.damagedets)
            {
                var i = 0;
                <tr>
                    <td>
                        @Html.EditorFor(model => item.name, new { htmlAttributes = new { @id = "damagedets[@i].name", @name = "damagedets[@i].name", @class = "form-control" } })
                    </td>
                 <!-- Data -- >
               </tr>
                i++;

            }
        </table>
        <h3>Attachments</h3>
        <table class="table table-striped table-bordered table-condensed">
            <tr>
                @foreach (var item in Model.imagedets)
                {
                    var i = 0;
                    @Html.HiddenFor(modelItem => item.benedet)
                    <input type="hidden" id="imagedets[@i].beneid" name="imagedets[@i].beneid" value="@item.beneid" />
                    <input type="hidden" id="imagedets[@i].url" name="imagedets[@i].url" value="@item.url" />
                    <input type="hidden" id="imagedets[@i].id" name="imagedets[@i].id" value="@item.id" />
                    <th>
                        <input class = "form-control" id="imagedets[@i].desc" name="imagedets[@i].desc" value="@item.desc" />
                        @*@Html.EditorFor(modelItem => item.desc, new { htmlAttributes = new { @id = "imagedets["+i+"].desc", name = "imagedets[@i].desc", @class = "form-control" } })*@
                    </th>
                    <td>

                        <img id="base64image[@i]" src="data:image/jpeg;base64, @ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(item.url))" />
                    </td>
                    i++;


                }
            </tr>
        </table>

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

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

Please guide me on how to achieve the above. Thanks for helping.

Link to Answer.

This is what I did.

  1. Changed the following in my base model

     public benedet() { this.bankdets = new HashSet<bankdet>(); this.damagedets = new HashSet<damagedet>(); this.imagedets = new HashSet<imagedet>(); } public virtual ICollection<bankdet> bankdets { get; set; } public virtual ICollection<damagedet> damagedets { get; set; } public virtual ICollection<imagedet> imagedets { get; set; } 

To

    public benedet()
    {
        this.bankdets = new List<bankdet>();
        this.damagedets = new List<damagedet>();
        this.imagedets = new List<imagedet>();
    }
    public virtual List<bankdet> bankdets { get; set; }

    public virtual List<damagedet> damagedets { get; set; }

    public virtual List<imagedet> imagedets { get; set; }
  1. Changed all foreach loops to for loops in the view.

  2. Edited the HTTPPOST EDIT method to iterate over all the items like this:

      [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit(benedet benedet) { if (ModelState.IsValid) { for(int i=0;i<benedet.damagedets.Count;i++) { db.Entry(benedet.damagedets[i]).State = EntityState.Modified; } for (int i = 0; i < benedet.bankdets.Count; i++) { db.Entry(benedet.bankdets[i]).State = EntityState.Modified; } for (int i = 0; i < benedet.imagedets.Count; i++) { db.Entry(benedet.imagedets[i]).State = EntityState.Modified; } db.Entry(benedet).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(benedet); } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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