EF Core 关系配置 一对多 双向导航属性
EF Core 支持一对多、多对对、一对一 关系。
一篇文章 Article 包含多条评论 Comment
Article(1)——》Comment(1,2,3...)
对于主从结构的“一对多”表关系,我们一般声明为双向导航属性,对于其它的“一对多”,则需根据情况决定使用单向导航属性还是双向导航属性。
例:被多个表都引用的基础表,一般都是声明单向导航属性。如用户,在采购单,入库单,表中都存在,关系不紧密,所以用单向导航。
实体类:
namespace EFCoreTest.Entities { /// <summary> /// 文章 /// </summary> public class Article { public long Id { get; set; } /// <summary> /// 标题 /// </summary> public string Title { get; set; } /// <summary> /// 内容 /// </summary> public string Content { get; set; } /// <summary> /// 文章的评论 /// </summary> public List<Comment> Comments { get; set; }=new List<Comment>(); } }
using System.Text.Json.Serialization; namespace EFCoreTest.Entities { /// <summary> /// 评论 /// </summary> public class Comment { public long Id { get; set; } /// <summary> /// 属于那篇文章 /// </summary> [JsonIgnore] public Article Article { get; set; } public long ArticleId { get; set; } /// <summary> /// 评论内容 /// </summary> public string Message { get; set; } } }
数据库表结构:
实体类的配置:
namespace EFCoreTest.Config { public class ArticleConfig : IEntityTypeConfiguration<Article> { public void Configure(EntityTypeBuilder<Article> builder) { builder.ToTable("T_Articles"); //双向导航属性关系定义,此关系也可以在ArticleConfig配置文件设定,二先一 //builder.HasMany<Comment>(c => c.Comments).WithOne(a => a.Article); builder.Property(x => x.Content).IsRequired().IsUnicode(); builder.Property(x => x.Title).IsRequired().IsUnicode().HasMaxLength(255); } } }
public class CommentConfig : IEntityTypeConfiguration<Comment> { public void Configure(EntityTypeBuilder<Comment> builder) { builder.ToTable("T_Comments"); //一个Article包含多个Comments,即一篇文章包含多条评论。 //前部分HasOne声明Comment和Article的关系是一对一 //后部分WithMany声明Article和Comment的关系是一对多 //双向导航属性关系定义,此关系也可以在ArticleConfig配置文件设定,二先一 builder.HasOne<Article>(c => c.Article).WithMany(a => a.Comments) .IsRequired().HasForeignKey(c => c.ArticleId); builder.Property(c => c.Message).IsRequired().IsUnicode(); } }
上下文配置文件 :
public class TestDbContext : DbContext { public TestDbContext(DbContextOptions options) : base(options) { } public DbSet<Article> Articles { get; set; } public DbSet<Comment> Comments { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.LogTo(Console.WriteLine); } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //加载当前程序集中所有实现了IEntityTypeConfiguration<T> 接口的类 modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly); } }