如何在 ASP.NET 核心 MVC 代码优先方法中的多个 table 中添加外键?
How to add foreign keys in multiple table in ASP.NET Core MVC code-first approach?
ApplicationDbContext.cs
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<BookReadingEvent> BookReadingEvents { get; set; }
public DbSet<Register> RegisterAccount { get; set; }
public DbSet<Login> LoginAccount { get; set; }
}
注册模型class:
namespace BookReadingEvents.Models
{
[Index(nameof(Email), IsUnique = true)]
public class Register
{
[Key]
public int RegisterId { get; set; }
[Required]
[DataType(DataType.EmailAddress, ErrorMessage = "Please enter a valid e-mail address")]
public string Email { get; set; }
[Required]
[Display(Name = "Full Name")]
public string Name { get; set; }
[Required]
[DataType(DataType.Password)]
[MinLength(5, ErrorMessage = "Password length cannot be less than 5")]
public string Password { get; set; }
[NotMapped] // Does not affect the database
[Compare("Password")]
[Required]
[DataType(DataType.Password)]
[Display(Name = "Confirm Password")]
public string ConfirmPassword { get; set; }
}
}
登录模式class:
public class Login
{
[Key]
public int LoginId { get; set; }
[Required]
[DataType(DataType.EmailAddress, ErrorMessage = "Please enter a valid e-mail address")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[MinLength(5, ErrorMessage = "Password length cannot be less than 5")]
public string Password { get; set; }
public DateTime EntryDate { get; set; } = DateTime.Now;
[ForeignKey("Registers")]
public int RegisterId { get; set; }
public virtual Register Registers { get; set; }
// Here foreign key is working fine
}
读书活动模型class:
public class BookReadingEvent
{
[Key]
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime Date { get; set; }
[Required]
public string Location { get; set; }
public string StartTime { get; set; }
public string EventType { get; set; }
[Range(1,9999)]
public int Duration { get; set; }
[StringLength(50, ErrorMessage = "Description length can't be more than 50.")]
public string Description { get; set; }
[StringLength(500, ErrorMessage = "Other Details length can't be more than 500.")]
public string Details { get; set; }
public string InviteByEmail { get; set; }
[ForeignKey("Registers")]
public int RegisterId { get; set; }
public virtual Register Registers { get; set; }
// Error: The ALTER TABLE statement conflicted with the FOREIGN KEY constraint
// "FK_BookReadingEvents_RegisterAccount_RegisterId". The conflict occurred in database
// "BookReadingEvents", table "dbo.RegisterAccount", column 'RegisterId'.
}
我也想将外键 RegisterId
添加到 BookReadingEventModel
中,但是当它在 Login
模型上正常工作时出现错误。如何使用代码优先方法将外键添加到读书事件 table?
如果您的数据库中有数据与您的更改相冲突,则会导致此错误。通过创建一个全新的迁移并运行它在一个新的空数据库上,可以很容易地对其进行测试。
您的数据库中很可能有无法引用的旧测试数据。
您在多个表中需要 RegisterId,这会导致错误。尝试使 RegisterId 在 classes
中都可以为空
public int? RegisterId { get; set; }
[ForeignKey("RegisterId")]
public virtual Register Register { get; set; }
并将导航属性也添加到寄存器 class
public class Register
{
[Key]
public int RegisterId { get; set; }
....
[InverseProperty(nameof(Login.Register))]
public virtual ICollection<Register> LoginRegisters {get; set;}
[InverseProperty(nameof(BookReadingEvent.Register))]
public virtual ICollection<Register> BookReadingEventRegisters {get; set;}
}
ApplicationDbContext.cs
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<BookReadingEvent> BookReadingEvents { get; set; }
public DbSet<Register> RegisterAccount { get; set; }
public DbSet<Login> LoginAccount { get; set; }
}
注册模型class:
namespace BookReadingEvents.Models
{
[Index(nameof(Email), IsUnique = true)]
public class Register
{
[Key]
public int RegisterId { get; set; }
[Required]
[DataType(DataType.EmailAddress, ErrorMessage = "Please enter a valid e-mail address")]
public string Email { get; set; }
[Required]
[Display(Name = "Full Name")]
public string Name { get; set; }
[Required]
[DataType(DataType.Password)]
[MinLength(5, ErrorMessage = "Password length cannot be less than 5")]
public string Password { get; set; }
[NotMapped] // Does not affect the database
[Compare("Password")]
[Required]
[DataType(DataType.Password)]
[Display(Name = "Confirm Password")]
public string ConfirmPassword { get; set; }
}
}
登录模式class:
public class Login
{
[Key]
public int LoginId { get; set; }
[Required]
[DataType(DataType.EmailAddress, ErrorMessage = "Please enter a valid e-mail address")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[MinLength(5, ErrorMessage = "Password length cannot be less than 5")]
public string Password { get; set; }
public DateTime EntryDate { get; set; } = DateTime.Now;
[ForeignKey("Registers")]
public int RegisterId { get; set; }
public virtual Register Registers { get; set; }
// Here foreign key is working fine
}
读书活动模型class:
public class BookReadingEvent
{
[Key]
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime Date { get; set; }
[Required]
public string Location { get; set; }
public string StartTime { get; set; }
public string EventType { get; set; }
[Range(1,9999)]
public int Duration { get; set; }
[StringLength(50, ErrorMessage = "Description length can't be more than 50.")]
public string Description { get; set; }
[StringLength(500, ErrorMessage = "Other Details length can't be more than 500.")]
public string Details { get; set; }
public string InviteByEmail { get; set; }
[ForeignKey("Registers")]
public int RegisterId { get; set; }
public virtual Register Registers { get; set; }
// Error: The ALTER TABLE statement conflicted with the FOREIGN KEY constraint
// "FK_BookReadingEvents_RegisterAccount_RegisterId". The conflict occurred in database
// "BookReadingEvents", table "dbo.RegisterAccount", column 'RegisterId'.
}
我也想将外键 RegisterId
添加到 BookReadingEventModel
中,但是当它在 Login
模型上正常工作时出现错误。如何使用代码优先方法将外键添加到读书事件 table?
如果您的数据库中有数据与您的更改相冲突,则会导致此错误。通过创建一个全新的迁移并运行它在一个新的空数据库上,可以很容易地对其进行测试。
您的数据库中很可能有无法引用的旧测试数据。
您在多个表中需要 RegisterId,这会导致错误。尝试使 RegisterId 在 classes
中都可以为空 public int? RegisterId { get; set; }
[ForeignKey("RegisterId")]
public virtual Register Register { get; set; }
并将导航属性也添加到寄存器 class
public class Register
{
[Key]
public int RegisterId { get; set; }
....
[InverseProperty(nameof(Login.Register))]
public virtual ICollection<Register> LoginRegisters {get; set;}
[InverseProperty(nameof(BookReadingEvent.Register))]
public virtual ICollection<Register> BookReadingEventRegisters {get; set;}
}