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

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 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://aka.ms/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语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
27天前
|
SQL 开发框架 .NET
代码更简洁,开发更高效:从零开始使用Entity Framework Core与传统ADO.NET构建数据持久化层的比较
【8月更文挑战第31天】在.NET平台上开发数据驱动应用时,选择合适的ORM框架至关重要。本文通过对比传统的ADO.NET和现代的Entity Framework Core (EF Core),展示了如何从零开始构建数据持久化层。ADO.NET虽强大灵活,但需要大量手写代码;EF Core则简化了数据访问,支持LINQ查询,自动生成SQL命令,提升开发效率。从创建.NET Core项目、定义数据模型、配置`DbContext`到执行数据库操作,EF Core提供了一套流畅的API,使数据持久化层的构建变得简单直接。
22 0
|
1月前
|
开发框架 .NET API
一个简单的 ASP.NET Core 依赖注入例子,提高代码的可维护性和可扩展性
一个简单的 ASP.NET Core 依赖注入例子,提高代码的可维护性和可扩展性
|
3月前
|
SQL 关系型数据库 数据库连接
详解 Entity Framework(EF)核心组件与数据访问方法探索
Entity Framework是一个ORM框架,简化.NET开发者与数据库的交互。它始于.NET Framework的一部分,但现在可通过NuGet独立获取。ORM允许对象模型直接映射到数据库结构,避免直接编写SQL。
265 2
详解 Entity Framework(EF)核心组件与数据访问方法探索
|
存储 关系型数据库 数据库连接
EF框架(一)搭建过程
EF:Entity Framework的简写,实体框架,EF是ADO.net的一组支持开发面向数据的软件应用程序的技术,是微软的一个orm框架。介绍EF框架之前,先带大家了解一下ORM。
|
前端开发
Yii2.0框架一共有哪些扩展?底层原理是什么?
Yii2.0框架一共有哪些扩展?底层原理是什么?
|
SQL 开发框架 .NET
5.2 EF Core性能优化
上文讲了实体类的跟踪以便执行SaveChanges操作。但是如果是查询操作,则实体类便不需要进行跟踪。
|
开发框架 .NET API
EF Core 数据验证
EF Core 数据验证
212 0
|
微服务
ASP.NET Core微服务之基于MassTransit实现数据最终一致性(2)
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一、案例结构与说明   在上一篇中,我们了解了MassTransit这个开源组件的基本用法,这一篇我们结合一个小案例来了解在ASP.NET Core中如何借助MassTransit+Quartz.Net来实现数据的最终一致性。
1408 0
|
微服务
ASP.NET Core微服务之基于MassTransit实现数据最终一致性(1)
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一、预备知识:数据一致性   关于数据一致性的文章,园子里已经有很多了,如果你还不了解,那么可以通过以下的几篇文章去快速地了解了解,有个感性认识即可。
1511 0
|
数据库 容器
.NET Core2.1下采用EFCore比较原生IOC、AspectCore、AutoFac之间的性能
一、前言  ASP.NET Core本身已经集成了一个轻量级的IOC容器,开发者只需要定义好接口后,在Startup.cs的ConfigureServices方法里使用对应生命周期的绑定方法即可,常见方法如下 services.
2718 0