The following code listing shows a one-to-many relationship between Blog
and Post
ide
Post
is the dependent entityui
Blog
is the principal entitythis
Post.BlogId
is the foreign keyspa
Blog.BlogId
is the principal key (in this case it is a primary key rather than an alternate key)code
Post.Blog
is a reference navigation propertyip
Blog.Posts
is a collection navigation propertyci
Post.Blog
is the inverse navigation property of Blog.Posts
(and vice versa)get
public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int BlogId { get; set; } public Blog Blog { get; set; } }
While it is recommended to have a foreign key property defined in the dependent entity class, it is not required. If no foreign key property is found, a shadow foreign key property will be introduced with the name string
public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } }
By convention, cascade delete will be set to Cascade for required relationships and ClientSetNull for optional relationships. it
detail:https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete
public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int BlogForeignKey { get; set; } [ForeignKey("BlogForeignKey")] public Blog Blog { get; set; } }
You can use the Data Annotations to configure how navigation properties on the dependent and principal entities pair up. This is typically done when there is more than one pair of navigation properties between two entity types.
has one with many
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>() .HasOne(p => p.Blog) .WithMany(b => b.Posts); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public Blog Blog { get; set; } }
same as without using the Fluent API because as it has been added automatically
Single Navigation Property
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasMany(b => b.Posts) .WithOne(); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } }
Foreign Key
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>() .HasOne(p => p.Blog) .WithMany(b => b.Posts) .HasForeignKey(p => p.BlogForeignKey); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int BlogForeignKey { get; set; } public Blog Blog { get; set; } }
composite foreign key.
class MyContext : DbContext { public DbSet<Car> Cars { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Car>() .HasKey(c => new { c.State, c.LicensePlate }); modelBuilder.Entity<RecordOfSale>() .HasOne(s => s.Car) .WithMany(c => c.SaleHistory) .HasForeignKey(s => new { s.CarState, s.CarLicensePlate }); } } public class Car { public string State { get; set; } public string LicensePlate { get; set; } public string Make { get; set; } public string Model { get; set; } public List<RecordOfSale> SaleHistory { get; set; } } public class RecordOfSale { public int RecordOfSaleId { get; set; } public DateTime DateSold { get; set; } public decimal Price { get; set; } public string CarState { get; set; } public string CarLicensePlate { get; set; } public Car Car { get; set; } }
class MyContext : DbContext { public DbSet<Car> Cars { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<RecordOfSale>() .HasOne(s => s.Car) .WithMany(c => c.SaleHistory) .HasForeignKey(s => s.CarLicensePlate) .HasPrincipalKey(c => c.LicensePlate); } } public class Car { public int CarId { get; set; } public string LicensePlate { get; set; } public string Make { get; set; } public string Model { get; set; } public List<RecordOfSale> SaleHistory { get; set; } } public class RecordOfSale { public int RecordOfSaleId { get; set; } public DateTime DateSold { get; set; } public decimal Price { get; set; } public string CarLicensePlate { get; set; } public Car Car { get; set; } }
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>() .HasOne(p => p.Blog) .WithMany(b => b.Posts) .IsRequired(); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public Blog Blog { get; set; } }
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>() .HasOne(p => p.Blog) .WithMany(b => b.Posts) .OnDelete(DeleteBehavior.Cascade); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int? BlogId { get; set; } public Blog Blog { get; set; } }
class MyContext : DbContext { public DbSet<Post> Posts { get; set; } public DbSet<Tag> Tags { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<PostTag>() .HasKey(t => new { t.PostId, t.TagId }); modelBuilder.Entity<PostTag>() .HasOne(pt => pt.Post) .WithMany(p => p.PostTags) .HasForeignKey(pt => pt.PostId); modelBuilder.Entity<PostTag>() .HasOne(pt => pt.Tag) .WithMany(t => t.PostTags) .HasForeignKey(pt => pt.TagId); } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public List<PostTag> PostTags { get; set; } } public class Tag { public string TagId { get; set; } public List<PostTag> PostTags { get; set; } } public class PostTag { public int PostId { get; set; } public Post Post { get; set; } public string TagId { get; set; } public Tag Tag { get; set; } }