代码之家  ›  专栏  ›  技术社区  ›  tintyethan

使用实体框架POST时出错-值不能为null。参数名称:来源

  •  1
  • tintyethan  · 技术社区  · 12 年前

    编辑-根据要求,这是视图。。。

    --开始编辑

    @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)
    }
    }
    

    --结束编辑

    --开始原始问题 我有一个包含两个类的viewModel。。。

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

    预订和跟踪是edmx中的实体。

    我想用一个保存调用来更新这两个类中的数据。

    这就是我尝试过的。。。

    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();
        }
    }
    

    如果我删除跟踪部分,预订部分将正确更新。

    这是GET方法。。。

    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);
    }
    

    这是我的数据库上下文类

    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);
        }
    }
    
    2 回复  |  直到 12 年前
        1
  •  1
  •   Travis J    12 年前

    问题似乎在于编辑器的设置方式。我认为这导致模型在提交时无法正确绑定

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

    如果你要检查 name 的属性 <input> 元素,您很可能会看到它读取

    <input name="item.contact_Name" />
    

    对于每一个。它甚至可能只是说 name="contact_Name" .

    这是该框架的一个严重缺陷,其解决方法通常是制作一个完整的自定义帮助程序或使用前端解决方案来修复名称。

    名称必须匹配 确切地 到模型。对你的价值观来说应该是

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

    因此,我建议找出一种适合您当前项目的方法,以确保这些名称得到正确设置。

        2
  •  0
  •   Az Za    12 年前

    在调用它之前,您没有检查vwbooking.traces==null。虽然您可能认为.ToList()可以保护您免受此影响,但实体框架可能很古怪(传闻)。使用保护您的通话

    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();
        }
    }
    

    你应该没事的。