.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

目录
相关文章
|
13天前
|
开发框架 NoSQL .NET
利用分布式锁在ASP.NET Core中实现防抖
【9月更文挑战第5天】在 ASP.NET Core 中,可通过分布式锁实现防抖功能,仅处理连续相同请求中的首个请求,其余请求返回 204 No Content,直至锁释放。具体步骤包括:安装分布式锁库如 `StackExchange.Redis`;创建分布式锁服务接口及其实现;构建防抖中间件;并在 `Startup.cs` 中注册相关服务和中间件。这一机制有效避免了短时间内重复操作的问题。
|
23天前
|
设计模式 存储 前端开发
揭秘.NET架构设计模式:如何构建坚不可摧的系统?掌握这些,让你的项目无懈可击!
【8月更文挑战第28天】在软件开发中,设计模式是解决常见问题的经典方案,助力构建可维护、可扩展的系统。本文探讨了.NET中三种关键架构设计模式:MVC、依赖注入与仓储模式,并提供了示例代码。MVC通过模型、视图和控制器分离关注点;依赖注入则通过外部管理组件依赖提升复用性和可测性;仓储模式则统一数据访问接口,分离数据逻辑与业务逻辑。掌握这些模式有助于开发者优化系统架构,提升软件质量。
33 5
|
23天前
|
XML 开发框架 .NET
.NET框架:软件开发领域的瑞士军刀,如何让初学者变身代码艺术家——从基础架构到独特优势,一篇不可错过的深度解读。
【8月更文挑战第28天】.NET框架是由微软推出的统一开发平台,支持多种编程语言,简化应用程序的开发与部署。其核心组件包括公共语言运行库(CLR)和类库(FCL)。CLR负责内存管理、线程管理和异常处理等任务,确保代码稳定运行;FCL则提供了丰富的类和接口,涵盖网络、数据访问、安全性等多个领域,提高开发效率。此外,.NET框架还支持跨语言互操作,允许开发者使用C#、VB.NET等语言编写代码并无缝集成。这一框架凭借其强大的功能和广泛的社区支持,已成为软件开发领域的重要工具,适合初学者深入学习以奠定职业生涯基础。
80 1
|
23天前
|
开发框架 监控 .NET
开发者的革新利器:ASP.NET Core实战指南,构建未来Web应用的高效之道
【8月更文挑战第28天】本文探讨了如何利用ASP.NET Core构建高效、可扩展的Web应用。ASP.NET Core是一个开源、跨平台的框架,具有依赖注入、配置管理等特性。文章详细介绍了项目结构规划、依赖注入配置、中间件使用及性能优化方法,并讨论了安全性、可扩展性以及容器化的重要性。通过这些技术要点,开发者能够快速构建出符合现代Web应用需求的应用程序。
31 0
|
23天前
|
缓存 数据库连接 API
Entity Framework Core——.NET 领域的 ORM 利器,深度剖析其最佳实践之路
【8月更文挑战第28天】在软件开发领域,高效的数据访问与管理至关重要。Entity Framework Core(EF Core)作为一款强大的对象关系映射(ORM)工具,在 .NET 开发中扮演着重要角色。本文通过在线书店应用案例,展示了 EF Core 的核心特性和优势。我们定义了 `Book` 实体类及其属性,并通过 `BookStoreContext` 数据库上下文配置了数据库连接。EF Core 提供了简洁的 API,支持数据的查询、插入、更新和删除操作。
38 0
|
27天前
|
开发框架 监控 .NET
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
|
27天前
|
Linux C# C++
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
|
1月前
|
存储 开发框架 .NET
ASP.NET Web Api 使用 EF 6,DateTime 字段如何取数据库服务器当前时间
ASP.NET Web Api 使用 EF 6,DateTime 字段如何取数据库服务器当前时间
|
1月前
|
程序员 数据库
分享 2 个 .NET EF 6 只更新某些字段的方法
分享 2 个 .NET EF 6 只更新某些字段的方法
|
1月前
|
数据库
分享一个 .NET EF 6 扩展 Where 的方法
分享一个 .NET EF 6 扩展 Where 的方法