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

示例

一对多

30.jpg

一个 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);

多对多

31.jpg

为 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

目录
相关文章
|
存储 Cloud Native 数据处理
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
本文整理自阿里云资深技术专家、Apache Flink PMC 成员梅源在 Flink Forward Asia 新加坡 2025上的分享,深入解析 Flink 状态管理系统的发展历程,从核心设计到 Flink 2.0 存算分离架构,并展望未来基于流批一体的通用增量计算方向。
295 0
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
|
3月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
本文内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
428 16
|
3月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
|
1月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
1月前
|
Java Linux 虚拟化
【Docker】(1)Docker的概述与架构,手把手带你安装Docker,云原生路上不可缺少的一门技术!
1. Docker简介 1.1 Docker是什么 为什么docker会出现? 假定您在开发一款平台项目,您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。 您正在开发的应用依赖于您当前的配置且还要依赖于某些配置文件。 您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。 **要求:**希望尽可能多在本地模拟这些环境而不产生重新创建服务器环境的开销 问题: 要如何确保应用能够在这些环境中运行和通过质量检测? 在部署过程中不出现令人头疼的版本、配置问题 无需重新编写代码和进行故障修复
339 2
|
1月前
|
人工智能 API 数据库
Semantic Kernel .NET 架构学习指南
本指南系统解析微软Semantic Kernel .NET架构,涵盖核心组件、设计模式与源码结构,结合实战路径与调试技巧,助你从入门到贡献开源,掌握AI编排开发全栈技能。
214 2
|
1月前
|
人工智能 Kubernetes Cloud Native
Higress(云原生AI网关) 架构学习指南
Higress 架构学习指南 🚀写在前面: 嘿,欢迎你来到 Higress 的学习之旅!
495 0
|
4月前
|
运维 监控 Cloud Native
从“守机器”到“写策略”——云原生架构把运维逼成了架构师
从“守机器”到“写策略”——云原生架构把运维逼成了架构师
108 1

热门文章

最新文章