替代键(备用关键字)

替代键充当了每个实体实例主键之外的备用唯一关键字。替代键可用于指定关系。在使用关系数据库的时候,替代键映射为备用关键字列上的唯一索引/约束这一概念,一个或者多个外键约束将引用这个(这些)列。

提示

如果你只想要实施某个列的唯一性,那么你想要的应该是唯一索引,而不是替代键,请查看 索引。在 EF 中,替代键比索引提供了更丰富的功能,因为它们可以用作外键的目标。

替代键通常在你需要的时候才被引入,并且你不需要手动配置他们。查看 惯例 以了解更多信息。

惯例

按照惯例,当你标识了某个非主键的属性时就会引入替代键,它将被用作关系的目标属性。

  1. class MyContext : DbContext
  2. {
  3. public DbSet<Blog> Blogs { get; set; }
  4. public DbSet<Post> Posts { get; set; }
  5. protected override void OnModelCreating(ModelBuilder modelBuilder)
  6. {
  7. modelBuilder.Entity<Post>()
  8. .HasOne(p => p.Blog)
  9. .WithMany(b => b.Posts)
  10. .HasForeignKey(p => p.BlogUrl)
  11. .HasPrincipalKey(b => b.Url);
  12. }
  13. }
  14. public class Blog
  15. {
  16. public int BlogId { get; set; }
  17. public string Url { get; set; }
  18. public List<Post> Posts { get; set; }
  19. }
  20. public class Post
  21. {
  22. public int PostId { get; set; }
  23. public string Title { get; set; }
  24. public string Content { get; set; }
  25. public string BlogUrl { get; set; }
  26. public Blog Blog { get; set; }
  27. }

数据注解

不能通过数据注解来配置替代键。

流式 API

可以使用流式 API 来将单一属性配置为替代键。

  1. class MyContext : DbContext
  2. {
  3. public DbSet<Car> Cars { get; set; }
  4. protected override void OnModelCreating(ModelBuilder modelBuilder)
  5. {
  6. modelBuilder.Entity<Car>()
  7. .HasAlternateKey(c => c.LicensePlate);
  8. }
  9. }
  10. class Car
  11. {
  12. public int CarId { get; set; }
  13. public string LicensePlate { get; set; }
  14. public string Make { get; set; }
  15. public string Model { get; set; }
  16. }

也可以使用流式 API 来将多个属性配置为替代键(通常称为组合替代键)。

  1. class MyContext : DbContext
  2. {
  3. public DbSet<Car> Cars { get; set; }
  4. protected override void OnModelCreating(ModelBuilder modelBuilder)
  5. {
  6. modelBuilder.Entity<Car>()
  7. .HasAlternateKey(c => new { c.State, c.LicensePlate });
  8. }
  9. }
  10. class Car
  11. {
  12. public int CarId { get; set; }
  13. public string State { get; set; }
  14. public string LicensePlate { get; set; }
  15. public string Make { get; set; }
  16. public string Model { get; set; }
  17. }