entity-framework - “当 IDENTITY_INSERT 设置为 OFF 时,无法在表 'x' 中插入标识列的显式值” - 使用嵌套自定义对象插入记录
问题描述
我收到错误“当 IDENTITY_INSERT 设置为 OFF 时,无法在表 'UserPermission' 中插入标识列的显式值”尝试插入如下记录:
dbContext.User.Add(someUser);
dbContext.SaveChanges();
话虽如此,User 文件将自定义类 UserPermission 作为其参数之一,并且someUser
UserPermission 不为 null 并且具有设置的 ID 参数。为什么会发生这种情况,是否可以避免出现此错误,而无需在我的 User 模型中显式添加 UserPermissionID 外键参数并将 UserPermission 参数设置为 null?
提前致谢。
解决方案
当反序列化在对象图中具有相关实体的实体然后尝试添加它们时,通常会发生此问题。UserPermission 可能是在数据库中设置有身份 PK 的现有记录,但 EF 似乎无法在实体定义中识别它。(即设置为DatabaseGenerated(DatabaseGeneratedOption.Identity)
。如果是这样,您很可能会看到一个不同的问题,即创建了一个全新的重复 UserPermission。
如果 someUser 及其关联的 someUser.UserPermission 是反序列化实体,那么您需要做一些工作以确保 EF 知道 UserPermission 是现有行:
void AddUser(User someUser)
{
var existingPermission = _context.UserPermissions.Local
.SingleOrDefault(x => x.UserPermissionId == someUser.UserPermission.UserPermissionId);
if (existingPermission != null)
someUser.UserPermission = existingPermission;
else
_context.Attach(someUser.UserPermission);
_context.Users.Add(someUser);
_context.SaveChanges();
}
简而言之,当使用 DbContext 可能未跟踪的分离实体时,我们需要检查该Local
ID 的任何现有跟踪实例的状态。如果我们找到一个,我们用分离的参考代替跟踪的参考。如果我们没有找到一个,我们在添加我们的用户之前附加分离的一个。
这仍然不完全安全,因为它假定引用的 UserPermission将存在于数据库中。如果出于任何原因发送了不存在的 UserPermission(行已删除或伪造数据),您将在保存时收到异常。
传递分离的实体引用起初似乎是一个简单的选项,但您需要为分离实体中的每个引用执行此操作。如果您只是Attach
在没有首先检查的情况下调用,它可能会工作,直到您遇到在运行时它不起作用的场景,因为上下文恰好已经在跟踪一个实例。
推荐阅读
- python - 为什么 vgg.prepare() 方法会创建给定图像的 9 个副本?
- python - 用于模式研究的 Python 正则表达式
- php - 如何显示输入数组的验证错误?
- ios - 在包含 collectionView 的 tableview XIB 中呈现 DocumentInteractionController
- java - 如何为 JButtons 设置动作侦听器以打开相应的面板
- c# - 如何在C#中选择保存excel文件的路径
- java - 获取存储在 WEB-INF 中的文件的相对路径?
- sql - 向 SQLite 提示特定列始终是排序的
- excel - 选择符合条件的下一个值
- exchangewebservices - 从 Outlook365 批量下载电子邮件