使用IdentityDbContext更新数据库时出现Failed executing DbCommand错误
排查步骤
- 先提取完整报错信息:执行
Update-Database(包管理控制台)或者dotnet ef database update命令时,完整输出日志会给出明确错误原因,其中Specified key was too long; max key length is 767 bytes类报错是该场景90%以上的诱因,即索引长度超出数据库限制 - 检查字段与字符集配置:如果使用MySQL/MariaDB数据库,
utf8mb4字符集下单字段索引最大支持191字符,你提供的建表语句中UserId、RoleId均为varchar(767),联合主键总长度达到1534字节,远超InnoDB引擎默认索引长度限制 - 检查外键一致性:确认
AspNetRoles.Id、AspNetUsers.Id两个主键的字段类型、长度和AspNetUserRoles表中RoleId、UserId完全匹配,类型不匹配也会触发外键创建失败 - 检查权限与已存在对象:确认当前数据库账号有建表、创建外键的权限,且
AspNetUserRoles表未提前创建,重复建表也会抛出执行失败错误
解决方法
方案1:调整Identity主键长度(推荐)
在你的IdentityDbContext实现类的OnModelCreating方法中,显式设置Identity相关字段的最大长度为191,适配utf8mb4字符集的索引限制:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 调整用户角色关联表字段长度 modelBuilder.Entity<AspNetUserRoles>(entity => { entity.Property(e => e.UserId).HasMaxLength(191); entity.Property(e => e.RoleId).HasMaxLength(191); }); // 同步调整关联表主键长度,避免外键不匹配 modelBuilder.Entity<AspNetUsers>(entity => { entity.Property(e => e.Id).HasMaxLength(191); }); modelBuilder.Entity<AspNetRoles>(entity => { entity.Property(e => e.Id).HasMaxLength(191); }); }
修改完成后删除原有迁移文件,重新执行Add-Migration [迁移名]和Update-Database即可正常执行。
方案2:修改主键类型
如果不需要字符串类型的主键,可以直接将Identity的主键类型改为int或者Guid,从根本上避免索引长度超限问题。
方案3:调整数据库索引限制(不推荐)
如果不想修改业务代码,可以修改MySQL配置文件,开启innodb_large_prefix参数,将单索引最大长度调整为3072字节,同时将表的行格式设置为DYNAMIC或COMPRESSED即可。该方案需要修改数据库配置,兼容性较差,不建议生产环境使用。
内容的提问来源于stack exchange,提问作者Анатолий Дудиев
相关产品推荐
相关产品推荐

