sql-server - 当 IDENTITY_INSERT 设置为 OFF 时,无法为表中的标识列插入显式值。”
问题描述
对于我的 API,我将 Entity Framework Core 与代码优先迁移一起使用。我创建了一些运行良好的关系。现在,我添加了另一个关系(一对多),突然间我被这个错误打了耳光:
Cannot insert explicit value for identity column in table 'Companies' when IDENTITY_INSERT is set to OFF."
Offcourse,我一定是做错了什么,但我就是不知道是什么。我遇到了更多这样的问题,答案是“将 IDENTITY_INSERT 设置为 ON”,但这对我不起作用,因为 EF 正在处理所有事情。
我的公司类可以属于一个组:
public class Company
{
// Primary key
public int Id { get; set; }
// The optional Id of a Group
public int? GroupID { get; set; }
...
}
和 Group 类:
public class Group
{
// Primary key
public int Id { get; set; }
// Name of the Group
public string Name { get; set; }
// List of Companies in this group
public IEnumerable<Company> Companies { get; set; }
}
用于处理 POST 的代码:
// POST api/groups
[HttpPost]
public async Task<IActionResult> Post([FromBody] Group group)
{
try
{
if (ModelState.IsValid)
{
_context.Groups.Add(group);
await _context.SaveChangesAsync();
return CreatedAtRoute("GetGroup", new { id = group.Id }, group);
}
return BadRequest(ModelState);
}
catch (Exception e)
{
return BadRequest($"Unable to create: {e.Message}");
}
}
在我的数据库中,所有列、索引和键都是按预期创建的,就像我在 API 中建立的所有其他一对多关系一样。但这个具体案例似乎最终以痛苦告终......
我试图添加到数据库的类:
解决方案
Problem is that there's no hint for EF to know if Company
(under Group
relationship) is being explicitly inserted or if it is supposed to use the pre-existing one from database.
Since those instanced are disconnected from DbContext
there is no indication whether they exist or not on the database by the time EF tries to generate its SQL command.
There is no easy way here, at least there was none by the time I've played with EF Core.
You should either:
- Change your code to only use the
ID
instead of the navigation property so you'll avoid this whenever possible, or; - Change your code to fetch related data (eg: fetch
Company
and attach it toGroup
) before saving desired data (eg: before savingGroup
).
So, for instance:
var companyDB = await context.Companies.SingleOrDefaultAsync(c => c.Id == group.Company.Id);
group.Company = companyDB;
context.Groups.Add(group);
await context.SaveChangesAsync();
Yes, you're making two trips to database. That's why I'd suggest using the first approach, so you can avoid this fetch and just save Group
entity directly into DB.
That does not, however, prohibits you from sending a navigation instace of Company
to your view. Just create some entity-related classes which will correlate to your database so you can load/save data using this entity type, and create a Dto
object which will be your endpoint input/output whenever needed.
Binding one into another can be done by using AutoMapper, manual linq or other approaches.
推荐阅读
- javascript - 如何在地图上绘制多边形时删除叠加层?
- outlook - 获取 singleValueExtendedProperties 时解析选择和展开失败错误
- c++ - 为什么 int myVar {5} 给出错误并且不起作用?
- sql - SparkSQL 中的表连接顺序以获得更好的性能
- python - 为什么我的代码没有显示任何输出。应该显示“未找到匹配项”
- flutter - Flutter 应用程序 - 想要在不被按下的情况下播放声音 oppressed()
- java - 了解链表中的插入
- linux - pid mem和tid mem的区别
- java - 如何在 Apache Beam 中使用 KafkaIO 指定 kafka 代理
- python - 如何从公司名称中提取电子邮件 ID