使用Microsoft.AspNetCore.Identity将ApplicationUser作为外键关联至其他表时的报错求助
解决IDENTITY_INSERT错误及实体关联问题
先直接解决你遇到的IDENTITY_INSERT设置为OFF的错误:
这个错误的核心原因是你的Document表的ID列是自增标识列(Entity Framework默认会把名为ID或DocumentID的主键设为自增),而你手动给它赋值了doc.ID = 1,当IDENTITY_INSERT处于OFF状态时,数据库不允许手动插入自增列的值。
快速修复错误
直接移除手动设置ID的代码即可:
AppUser user = await _userManager.FindByEmailAsync("test@local.local"); Document doc = new Document(); // 删掉这一行:doc.ID = 1; doc.DESC= "DESC1"; doc.SLUG= "SLUG1"; doc.AppUser = user; // 这里注意你的原代码写的是doc.UserId = user; 应该改成doc.AppUser = user; 或者用下面的外键方式
如果你确实有特殊需求要手动插入ID值(不推荐常规场景这么做),可以在保存前开启IDENTITY_INSERT,示例如下:
using var transaction = await _context.Database.BeginTransactionAsync(); _context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT [Document] ON"); _context.Documents.Add(doc); await _context.SaveChangesAsync(); _context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT [Document] OFF"); await transaction.CommitAsync();
顺便纠正你的实体类关联问题
从你的代码看,实体关系还有一些需要调整的地方:
- AppUser与Document的一对多关系:一个用户应该可以拥有多个文档,所以AppUser里的导航属性应该是集合类型,而不是单个Document:
public class AppUser : IdentityUser { public string FirstName { get; set; } public string LastName { get; set; } // 改成集合,初始化避免空引用 public ICollection<Document> Documents { get; set; } = new List<Document>(); }
- Document的外键字段缺失:你只定义了导航属性
AppUser,但没有显式的外键字段,而且ForeignKey属性的使用也有问题。因为IdentityUser的主键默认是string类型,所以Document里应该添加对应的外键字段:
public class Document { public int ID { get; set; } public string DESC{ get; set; } public string SLUG{ get; set; } // 显式定义外键字段,类型和AppUser的主键一致(默认是string) public string UserID { get; set; } // 关联外键字段和导航属性 [ForeignKey(nameof(UserID))] public AppUser AppUser { get; set; } }
- 关联代码的小错误:你原代码里写的
doc.UserId = user;是错误的,应该改成下面两种方式之一:- 方式一:直接赋值导航属性
doc.AppUser = user; - 方式二:赋值外键字段(更高效,不需要加载完整的User实体)
doc.UserID = user.Id;
- 方式一:直接赋值导航属性
调整完这些后,再保存数据就不会再遇到IDENTITY_INSERT的错误,同时实体关联也能正常工作了。
内容的提问来源于stack exchange,提问作者dalia
相关产品推荐
相关产品推荐

