.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

目录
相关文章
|
8月前
|
人工智能 API 数据库
Semantic Kernel .NET 架构学习指南
本指南系统解析微软Semantic Kernel .NET架构,涵盖核心组件、设计模式与源码结构,结合实战路径与调试技巧,助你从入门到贡献开源,掌握AI编排开发全栈技能。
953 2
|
自然语言处理 JavaScript Java
《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》学习笔记——HarmonyOS架构介绍
HarmonyOS采用分层架构设计,从下至上分为内核层、系统服务层、框架层和应用层。内核层支持多内核设计与硬件驱动;系统服务层提供核心能力和服务;框架层支持多语言开发;应用层包括系统及第三方应用,支持跨设备调度,确保一致的用户体验。
1432 81
|
机器学习/深度学习 存储 编解码
RT-DETR改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
RT-DETR改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
520 16
RT-DETR改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
|
机器学习/深度学习 存储 编解码
YOLOv11改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
YOLOv11改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
618 7
YOLOv11改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
|
人工智能 前端开发 Java
DDD四层架构和MVC三层架构的个人理解和学习笔记
领域驱动设计(DDD)是一种以业务为核心的设计方法,与传统MVC架构不同,DDD将业务逻辑拆分为应用层和领域层,更关注业务领域而非数据库设计。其四层架构包括:Interface(接口层)、Application(应用层)、Domain(领域层)和Infrastructure(基础层)。各层职责分明,避免跨层调用,确保业务逻辑清晰。代码实现中,通过DTO、Entity、DO等对象的转换,结合ProtoBuf协议,完成请求与响应的处理流程。为提高复用性,实际项目中可增加Common层存放公共依赖。DDD强调从业务出发设计软件,适应复杂业务场景,是微服务架构的重要设计思想。
|
开发框架 前端开发 .NET
一个适用于 .NET 的开源整洁架构项目模板
一个适用于 .NET 的开源整洁架构项目模板
363 26
|
敏捷开发 缓存 中间件
.NET技术的高效开发模式,涵盖面向对象编程、良好架构设计及高效代码编写与管理三大关键要素
本文深入探讨了.NET技术的高效开发模式,涵盖面向对象编程、良好架构设计及高效代码编写与管理三大关键要素,并通过企业级应用和Web应用开发的实践案例,展示了如何在实际项目中应用这些模式,旨在为开发者提供有益的参考和指导。
210 3
|
存储 消息中间件 前端开发
.NET常见的几种项目架构模式,你知道几种?
.NET常见的几种项目架构模式,你知道几种?
531 0