EF创建数据库时为何User表生成RoleLookupId、RoleLookupId1两列
问题原因
出现重复外键列是两个问题共同导致的:
- 外键与主键类型不匹配:
User类中定义的RoleLookupId属性为int类型,但RoleLookup类的主键RoleLookupId是short类型,Entity Framework 无法将现有RoleLookupId属性识别为导航属性RoleLookup对应的外键,会按照约定自动生成一个类型匹配的外键列,也就是你看到的RoleLookupId1。 - 缺少显式外键绑定:你没有通过特性或Fluent API显式指定
RoleLookup导航属性对应的外键字段,在类型不匹配的情况下,EF的约定配置无法自动关联现有属性和导航属性,就会额外生成外键字段。
另外你给int类型的RoleLookupId加的[MaxLength(1)]特性是无效的,该特性仅用于限制字符串、字节数组等类型的长度,对数值类型不生效,可以直接删除。
修复方法
两种方案选其一即可,操作前建议先删除之前生成的错误迁移文件。
方案1:使用数据注解特性修复
- 将
User类中RoleLookupId的类型从int改为short,和RoleLookup主键类型保持一致 - 给
RoleLookup导航属性添加[ForeignKey]特性,显式指定关联的外键属性
修改后的User类代码如下:
namespace Faculty_Information_System_Application.Data { public class User { [Key] public int UserId { get; set; } [Required(ErrorMessage = "Please Enter the Role")] public short RoleLookupId { get; set; } [Required(ErrorMessage = "Please Enter username Name"), MaxLength(10)] public string UserName { get; set; } [Required] [DataType(DataType.Password)] public string Password { get; set; } [ForeignKey(nameof(RoleLookupId))] public virtual RoleLookup RoleLookup {get; set;} } }
方案2:使用Fluent API配置关系
如果不想在实体类上加特性,可以在DbContext的OnModelCreating方法中配置一对多关系,注意要先统一外键和主键的类型:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<User>() .HasOne(u => u.RoleLookup) .WithMany(r => r.Users) .HasForeignKey(u => u.RoleLookupId) .HasPrincipalKey(r => r.RoleLookupId); // 其他原有配置... }
配置完成后重新生成迁移并更新数据库,User表就只会保留一个RoleLookupId外键列,不会再生成多余的RoleLookupId1字段。
内容的提问来源于stack exchange,提问作者Gaurish Ninnekar
相关产品推荐
相关产品推荐

