ASP.NET - 多次绑定模型
ASP.NET - Binding a Model multiple times
我有两个模型:Machine
和 Devices
。
它们之间的关系是:AMachine
有一个集合Devices
.
PostAction 应该如何工作: 当用户创建一个新的 Machine
时,他还将声明 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 个设备时,调试显示的内容如下:
如图所示,第一次尝试时 DeviceID 为 0。第二次尝试时为 1006。此 DeviceID 是自动生成的。
此时应用程序中断声明:
SqlException: Cannot insert explicit value for identity column in table 'Device' when IDENTITY_INSERT is set to OFF.
我相信这是因为它试图在关键字段 (DeviceID) 上写一个零。
而且,它还在数据库中保存了一个寄存器:
但它保存了两次尝试的组合:(1) 尝试 1 的 DeviceName,(2) 尝试 2 的 DeviceID。
谁能解释一下为什么在第一次尝试时 DeviceID 为零?这怎么能解决?为什么它保存了两种尝试的组合?
提前致谢。
根据我在您的代码中了解到的情况,您的循环正在遍历它认为它基于机器模型中自动绑定的设备数量的设备数量,我假设有一只手- 在您的 MVC 表单上输入值。
对于每个 "Device" 它有,你实际上是在试图告诉 Entity Framework 添加相同的对象(在它修改了它的属性之后)并将它保存到数据库中。在第一个 "SaveChanges" 调用之后,设备的 Id 列将更新为数据库分配给它的 ID。如果您随后尝试再次将其添加到 DBContext ,它将尝试创建一个具有相同 ID 的新设备,这是非法的,除非如其所说,IDENTITY_INSERT 是设置为开。即使该设置为 ON,由于可能的唯一性约束,它也是非法的。
因此,首先,更好的做法是拥有断开连接的模型,然后是将这些模型转换为实际实体并将其插入数据库的数据层。但是,除此之外,像这样每次都会创建一个新设备的方法会更好:
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");
}
我有两个模型:Machine
和 Devices
。
它们之间的关系是:AMachine
有一个集合Devices
.
PostAction 应该如何工作: 当用户创建一个新的 Machine
时,他还将声明 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 个设备时,调试显示的内容如下:
如图所示,第一次尝试时 DeviceID 为 0。第二次尝试时为 1006。此 DeviceID 是自动生成的。
此时应用程序中断声明:
SqlException: Cannot insert explicit value for identity column in table 'Device' when IDENTITY_INSERT is set to OFF.
我相信这是因为它试图在关键字段 (DeviceID) 上写一个零。
而且,它还在数据库中保存了一个寄存器:
但它保存了两次尝试的组合:(1) 尝试 1 的 DeviceName,(2) 尝试 2 的 DeviceID。
谁能解释一下为什么在第一次尝试时 DeviceID 为零?这怎么能解决?为什么它保存了两种尝试的组合?
提前致谢。
根据我在您的代码中了解到的情况,您的循环正在遍历它认为它基于机器模型中自动绑定的设备数量的设备数量,我假设有一只手- 在您的 MVC 表单上输入值。
对于每个 "Device" 它有,你实际上是在试图告诉 Entity Framework 添加相同的对象(在它修改了它的属性之后)并将它保存到数据库中。在第一个 "SaveChanges" 调用之后,设备的 Id 列将更新为数据库分配给它的 ID。如果您随后尝试再次将其添加到 DBContext ,它将尝试创建一个具有相同 ID 的新设备,这是非法的,除非如其所说,IDENTITY_INSERT 是设置为开。即使该设置为 ON,由于可能的唯一性约束,它也是非法的。
因此,首先,更好的做法是拥有断开连接的模型,然后是将这些模型转换为实际实体并将其插入数据库的数据层。但是,除此之外,像这样每次都会创建一个新设备的方法会更好:
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");
}