문제

EDIT - as requested, this is the view...

--start edit

@model salesWebTest.viewModel.vwbooking

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

@Html.HiddenFor(model => model.bookings.bookingid)
@Html.EditorFor(model => model.bookings.name)

@foreach (var item in Model.traces)
{
    @Html.EditorFor(m => item.contact_Name)
}
}

--end edit

--start original question I have a viewModel that contains two classes...

public class vwbooking
{
    public booking bookings { get; set; }
    public IEnumerable<trace> traces { get; set; }
}

Booking and trace are entities in an edmx.

I want to update the data in these two class with one call to save.

This is what I've tried...

public ActionResult Edit(vwbooking vwbooking)
{
    if (ModelState.IsValid)
    {
        db.bookings.Attach(vwbooking.bookings);
        db.Entry(vwbooking.bookings).State = EntityState.Modified;
        vwbooking.traces.ToList().ForEach( //THE ERROR OCCURS HERE
                  t =>
                  {
                      db.traces.Attach(t);
                      db.Entry(t).State = EntityState.Modified;
                  });
        db.SaveChanges();
    }
}

If I remove the traces portion, the booking portion will update correctly.

This is the GET method...

public ActionResult Edit(int id = 0)
{
    booking booking = db.bookings.Find(id);
    var viewModel = new vwbooking();
    viewModel.bookings = booking;
    viewModel.traces = (from l in db.traces where l.bookingid == booking.bookingid select l);
    return View(viewModel);
}

This is my db context class

public class salesContext : DbContext
{
    public salesContext() : base()
    {
        Configuration.LazyLoadingEnabled = true;
    }

    public salesContext(string Connection) : base(Connection)
    {
        Configuration.LazyLoadingEnabled = true;
    }

    public DbSet<booking> bookings { get; set; }
    public DbSet<trace> traces { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<booking>().HasKey(e => e.bookingid);
        modelBuilder.Entity<trace>().HasKey(e => e.traceid);
    }
}
도움이 되었습니까?

해결책

The issue appears to be the way the editor is setup. I believe that this is causing the model to not properly bind on submit

@Html.EditorFor(m => item.contact_Name)

If you were to inspect the name attribute of the <input> element generated by this helper, you will more than likely see that it reads

<input name="item.contact_Name" />

for every one of these. It may even just say name="contact_Name".

This is a severe drawback of the framework and the workarounds for it are usually to make a whole custom helper or to use a front end solution to fix the names.

The name must match exactly to the model. What it should be for your values is

<input name="traces[0].contact_Name" />
<input name="traces[1].contact_Name" />
etc..

and so I would suggest figuring out a way that works with your current project to make sure that those names get properly set.

다른 팁

Your not checking if vwbooking.traces == null before calling it. While you might expect that .ToList() can protect you from this, Entity Framework can be quirky (anecdotal). Safeguard your call with

if (ModelState.IsValid)
{

    db.bookings.Attach(vwbooking.bookings);
    db.Entry(vwbooking.bookings).State = EntityState.Modified;
    if(vwbooking.traces != null)
    {
            vwbooking.traces.ToList().ForEach( //THE ERROR OCCURS HERE
            t =>
            {
            db.traces.Attach(t);
            db.Entry(t).State = EntityState.Modified;
            }
        );
        db.SaveChanges();
    }
}

and you should be fine.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top