ASP.NET - 多次绑定模型

时间:2017-09-05 18:08:53

标签: c# asp.net http-post model-binding

我有两个模型:MachineDevices

它们之间的关系是:Machine的集合为Devices

PostAction应如何运作:当用户创建新的Machine时,他还会声明该机器的Devices个数。

这样,如果为机器声明了3个设备,则必须在Device模型上保存3个寄存器。

守则:

    [HttpPost, ActionName("CreateEdit")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> CreateEditPost(int? id,
        [Bind("TypeID,BrandID,SupplierID,StoreID,MchName,NumDevices,FechaCompra,CostoMaq,MachineStatus")]Machine model,
        [Bind("Id,DeviceName")]Device devicemodel)
    {
        if (id == null)
        {
            return NotFound();
        }

        if (ModelState.IsValid)
        {
            if (id == 0)
            {
                _context.Add(model);
                for (var items = 0; items < model.NumDevices; items++)
                {
                    var contador = items + 1;
                    string devicename = model.MchName + "-" + contador.ToString();
                    devicemodel.DeviceName = devicename;
                    _context.Add(devicemodel);
                    await _context.SaveChangesAsync();
                }
                await _context.SaveChangesAsync();
                return RedirectToAction("Index");
            }
        }
        return RedirectToAction("Index");
    }

问题:

例如,当指示2个设备时,这是调试显示的内容:

enter image description here

如图所示,在第一次尝试时,DeviceID为0.在第二次尝试中为1006.此DeviceID是自动生成的。

此时应用程序中断声称:

  

SqlException:无法在表&#39;设备&#39;中插入标识列的显式值。当IDENTITY_INSERT设置为OFF时。

我相信这是因为它试图在Key字段(DeviceID)上写入零。

但是,它还在数据库中保存了一个注册表:

enter image description here

但它保存了两次尝试的组合:(1)尝试1的DeviceName,(2)尝试2的DeviceID。

有人可以解释为什么在第一次尝试时DeviceID为零?怎么解决这个问题?为什么它可以节省两种尝试的组合?

提前致谢。

1 个答案:

答案 0 :(得分:1)

从我在你的代码中可以看出,你的循环经历了它认为它基于机器模型中自动绑定设备数量的设备数量,我假设有一个手动输入MVC表单上的值。

对于每个&#34;设备&#34;它有,你真的试图告诉实体框架添加相同的对象(在它的属性修改后)并将其保存到数据库。在第一次&#34; SaveChanges&#34;呼叫时,设备的Id列将更新为数据库分配给它的ID。如果您尝试再次将其添加到DBContext ,它将尝试创建具有SAME ID的新设备,这是非法的,除非,如上所述,IDENTITY_INSERT设置为ON。即使它设置为ON,由于可能存在唯一性限制,它也是非法的。

因此,首先,拥有DISCONNECTED模型是一种更好的做法,然后是将这些模型转换为实际实体并将其插入数据库的数据层。但是,除此之外,每次都会创建一个新设备,这样做会更好:

        if (id == 0)
        {
            _context.Add(model);
            for (var items = 0; items < model.NumDevices; items++)
            {
                var contador = items + 1;
                string devicename = model.MchName + "-" + contador.ToString();
                var devNew = new Device();
                devNew.DeviceName = devicename;
                _context.Add(devNew);
                await _context.SaveChangesAsync();
            }
            await _context.SaveChangesAsync();
            return RedirectToAction("Index");
        }