zoukankan      html  css  js  c++  java
  • .NET 云原生架构师训练营(模块二 基础巩固 EF Core 关系)--学习笔记

    2.4.4 EF Core -- 关系

    • 一对多
    • 一对一
    • 多对多
    • 示例

    关系:https://docs.microsoft.com/zh-cn/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key

    一对多

    // Dependent Entity 主表
    public class Blog
    {
        // Principal Key 标识键/可能是主键或者备用键(唯一性约束)
        public int BlogId { get; set; }
        
        public string Url { get; set; }
    
        // Collection navigation property 关联多个从表的属性集合(集合属性)
        public List<Post> Posts { get; set; }
    }
    
    // Principal Entity 从表
    public class Post
    {
        public int PostId { get; set; }
        
        public string Title { get; set; }
        
        public string Content { get; set; }
    
        // Foreign Key 外键(指向主表中的 Principal Key)
        // Inverse navigation property 反向导航属性
        public int BlogId { get; set; }
    
        // Inverse navigation property 反向导航属性
        public Blog Blog { get; set; }
    }
    

    一对一

    // Principal Entity 从表
    public class Blog
    {
        public int BlogId { get; set; }
        
        public string Url { get; set; }
    
        public List<Post> Posts { get; set; }
    }
    
    // Dependent Entity 主表
    public class Post
    {
        public int PostId { get; set; }
        
        public string Title { get; set; }
        
        public string Content { get; set; }
    
        // Reference navigation property 一对一时指向另外一张表(引用属性)
        public Blog Blog { get; set; }
    }
    

    多对多

    public class Post
    {
        public int PostId { get; set; }
        
        public string Title { get; set; }
        
        public string Content { get; set; }
    
        public ICollection<Tag> Tags { get; set; }
    }
    
    public class Tag
    {
        public string TagId { get; set; }
    
        public ICollection<Post> Posts { get; set; }
    }
    

    示例

    一对多

    一个 Project 对应多个 ProjectGroup

    在 Project 实体中添加 ProjectGroup 列表

    public List<ProjectGroup> Groups { get; set; }
    

    迁移

    dotnet ef migrations add ProjectGroupCollectionProperty
    

    生成集合属性 ProjectGroupCollectionProperty

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<string>(
            name: "ProjectId",
            table: "ProjectGroups",
            nullable: true,
            oldClrType: typeof(string),
            oldType: "longtext CHARACTER SET utf8mb4",
            oldNullable: true);
    
        migrationBuilder.CreateIndex(
            name: "IX_ProjectGroups_ProjectId",
            table: "ProjectGroups",
            column: "ProjectId");
    
        migrationBuilder.AddForeignKey(
            name: "FK_ProjectGroups_Projects_ProjectId",
            table: "ProjectGroups",
            column: "ProjectId",
            principalTable: "Projects",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);
    }
    

    手动配置

    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; }
    }
    

    LighterDbContext

    // 一对一
    modelBuilder.Entity<Project.ProjectGroup>().HasOne<Project.Project>(g => g.Project);
    // 一对多
    modelBuilder.Entity<Project.ProjectGroup>().HasOne<Project.Project>(g => g.Project).WithMany(p => p.Groups);
    

    多对多

    为 Project 和 Subject 建立中间表 SubjectProject

    public class Project : Entity
    {
        public string Title { get; set; }
    
        public DateTime StartDate { get; set; }
    
        public DateTime EndDate { get; set; }
    
        public string SupervisorId { get; set; }
    
        public string PlanId { get; set; }
    
        public List<ProjectGroup> Groups { get; set; }
        
        public List<SubjectProject> SubjectProjects { get; set; }
    }
    
    public class Subject : Entity
    {
        public string Title { get; set; }
    
        public string Content { get; set; }
        
        public List<SubjectProject> SubjectProjects { get; set; }
    }
    
    public class SubjectProject : Entity
    {
        public string ProjcetId { get; set; }
    
        public Project Project { get; set; }
    
        public string SubjectId { get; set; }
    
        public Subject Subject { get; set; }
    }
    

    配置多对多关系

    LighterDbContext

    // 多对多(两组一对多)
    modelBuilder.Entity<Project.SubjectProject>()
        .HasOne<Project.Project>(s => s.Project)
        .WithMany(p => p.SubjectProjects)
        .HasForeignKey(s => s.ProjcetId);
        
    modelBuilder.Entity<Project.SubjectProject>()
        .HasOne<Project.Subject>(s => s.Subject)
        .WithMany(p => p.SubjectProjects)
        .HasForeignKey(s => s.SubjectId);
    

    迁移

    dotnet ef migrations add SubjectProjectManyToManyRelation
    

    SubjectProjectManyToManyRelation

    table.ForeignKey(
        name: "FK_SubjectProject_Projects_ProjcetId",
        column: x => x.ProjcetId,
        principalTable: "Projects",
        principalColumn: "Id",
        onDelete: ReferentialAction.Restrict);
    table.ForeignKey(
        name: "FK_SubjectProject_Subject_SubjectId",
        column: x => x.SubjectId,
        principalTable: "Subject",
        principalColumn: "Id",
        onDelete: ReferentialAction.Restrict);
    

    中间表创建了两个外键,形成多对多

    EF Core 5.0 多对多实现

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
    
        public ICollection<Tag> Tags { get; set; }
    }
    
    public class Tag
    {
        public string TagId { get; set; }
    
        public ICollection<Post> Posts { get; set; }
    }
    

    迁移的时候会自动生成中间表

    联接实体类型配置 HasMany

    modelBuilder
        .Entity<Post>()
        .HasMany(p => p.Tags)
        .WithMany(p => p.Posts)
        .UsingEntity(j => j.ToTable("PostTags"));
    

    GitHub源码链接:

    https://github.com/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/LighterApi

    知识共享许可协议

    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

    欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

    如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。

  • 相关阅读:
    20145322《信息安全系统设计基础》第13周学习总结
    20145310《信息安全系统设计基础》实验五 网络通信
    《信息安全系统设计基础》实验四 外设驱动程序设计
    《信息安全系统设计基础》实验二 固件设计
    《信息安全系统设计基础》实验三报告
    20145321《信息安全系统设计基础》第14周学习总结
    20145321 《信息安全系统设计基础》第13周学习总结
    《信息安全系统设计基础》实验五报告
    20145321 《信息安全系统设计基础》第12周学习总结
    《信息安全系统设计基础》实验四报告
  • 原文地址:https://www.cnblogs.com/MingsonZheng/p/14209347.html
Copyright © 2011-2022 走看看