目录
5. appsettings.Development.json文件(配置数据库链接)
2. 使用 EF Core Power Tools 插件生成模型类
一、EF Core
1. 使用的ORM框架(对象关系映射)
可理解为将数据库作为对象来进行操作。
2. EFCore 常见两种模式
DBFirst(数据库优先)、CodeFirst(代码优先)
3. EFCore 提供程序
安装程序:右击整个方案(而不是单个专案) > 选择“管理方案的NuFet套件” > 浏览选项卡下,搜索所需程序 > 选中需要安装的专案 > 点击安装 > 弹出的提示框选择套用和接受。
二、 EF 操作数据库(Code First)
1. 下载NuGet插件
Microsoft.AspNetCore.App
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameWorkCore.Tools (针对数据库迁移)
Microsoft.EntityFrameworkCore.Design(设计库,数据库转为ORM)
Npgsql
Npgsql.EntityFrameworkCore.PostgreSQL (针对PostgreSQL数据库)
2. 创建模型类文件(创建实体类)
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ASPNetAPI.Models
{
[Table("myapp_music")]
[Index(nameof(MusicName))] // 单个索引
[Index(nameof(MusicName), nameof(Singer), IsUnique = true)] // 联合索引
public class Music
{
[Key] // 每个表必须存在主键(要么是设置Key属性、要么栏位后缀是ID)
[Column("music_id")]
public int MusicID { get; set; }
[Display(Name = "歌名")]
[Required(ErrorMessage ="请输入歌名")]
[Column("music_name")]
public string MusicName { get; set; }
[MaxLength(50, ErrorMessage = "描述内容不超过50个字符")]
[Required(ErrorMessage = "请输入歌曲说明")]
[Column("desc")]
public string Description { get; set; }
[Required(ErrorMessage = "请选择歌手")]
[Column("singer")]
public MusicSingersEnum? Singer { get; set; }
[Column("playtimes")]
public int PlayTimes { get; set; }
[Column("price")]
public double SongPrice { get; set; }
}
}
3. 创建DBContext文件(创建数据库上下文)
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Repository.Music.Models;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace ASPNetAPI.Context; // 命名空间
public class MusicDbContext : DbContext // 继承DbContext
{
public MusicDbContext(DbContextOptions<MusicDbContext> options)
: base(options) // 实例化DbContextOptions
{
}
public virtual DbSet<Music> Music { get; set; } // 对DbContext类的所有实体,添加DbSet<TEntity泛型> 属性。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//=> optionsBuilder.UseNpgsql("DATA SOURCE=XX.XX.XXX.X;PASSWORD=123;PERSIST SECURITY INFO=True;USER ID=luobogan");
=> optionsBuilder.UseOracle("User Id = luobogan; Password=123;Data Source = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = XX.XX.XXX.X)(PORT = 1521)))(CONNECT_DATA = (SERVICE_NAME = Book)))");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
foreach (var entity in modelBuilder.Model.GetEntityTypes()) // 遍历所有实体类型
{
entity.SetTableName(entity.GetTableName().ToUpper()); // 表名大写
foreach (var property in entity.GetProperties())
{
// 针对属性的列类型是布尔值,进行修改
if (property.ClrType == typeof(bool))
{
// 设置 ValueConverter,将数据库中bool类型的列值与代码中char字符值自动转换(数据库中存储 'T' / 'F',ORM操作的是True/False)
property.SetValueConverter(
new ValueConverter<bool, string>(
v => v ? "T" : "F", // 将 bool 转换为字符('T' 或 'F')
v => v == "T" // 将 字符 转换为 bool('T' 转换为 True,其他为 False)
)
);
// 更新列类型为 string(如 CHAR(1) 或 VARCHAR(1))
property.SetColumnType("CHAR(1)");
}
property.SetColumnName(property.GetColumnName().ToUpper()); // 列名大写
}
}
}
}
4. Programs.cs文件(连接数据库)
using Microsoft.EntityFrameworkCore;
using ASPNetAPI.Models;
…
builder.Services.AddDbContextPool<MusicDbContext>(
options => options.UseNpgsql(builder.Configuration.GetConnectionString("MusicConn")) // 针对的是postgreDB
);
5. appsettings.Development.json文件(配置数据库链接)
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"MusicConn": "Host=10.XXX.XX.XX;Database=music_db;User Id=luobogan;Password=luobo.123;"
}
}
三、DBContext文件的基础设置
(一)表名和栏位名都大写
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// 遍历所有实体类型
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{ // 表名大写
entity.SetTableName(entity.GetTableName().ToUpper());
foreach (var property in entity.GetProperties())
{
// 所有列名大写
property.SetColumnName(property.GetColumnName().ToUpper());
}
}
}
(二)布尔值栏位的存储
1.DBContext文件的内容:
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// 遍历所有实体类型
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
foreach (var property in entity.GetProperties())
{
// 针对属性的列类型是布尔值,进行修改
if (property.ClrType == typeof(bool))
{
// 设置 ValueConverter,将数据库中bool类型的列值与代码中char字符值自动转换(数据库中存储 'T' / 'F',ORM操作的是True/False)
property.SetValueConverter(
new ValueConverter<bool, string>(
v => v ? "T" : "F", // 将 bool 转换为字符('T' 或 'F')
v => v == "T" // 将 字符 转换为 bool('T' 转换为 True,其他为 False)
)
);
// 更新列类型为 string(如 CHAR(1) 或 VARCHAR(1))
property.SetColumnType("CHAR(1)");
}
}
}
}
2.测试的Controller文件(配合Swagger):
using Microsoft.AspNetCore.Mvc;
using System.Data;
using Api.Models.Response;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using Repository.mes.Models;
using Repository.mes.Context;
using System.Linq;
namespace Api.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class TestBoolController(MusicContext context) : @base.BaseController()
{
private readonly MusicContext _context = context;
[HttpGet]
[DisplayName("【查詢】布尔值测试")]
public async Task<ActionResult<ResponseDto<IEnumerable<MusicSuperUser>>>> Get()
{
var music_qry = _context.MusicSuperUsers.AsQueryable();
var res_qry = music_qry.Select(m => new
{
m.Active,
m.Freeze,
m.Createuser
}).ToList();
var get_act = res_qry[0].Active;
if (get_act)
{
return Ok(message: "这是True值:" + get_act);
}
return Ok(message: "这是False值"+ get_act);
}
}
}
四、EF 执行迁移
五、根据数据库生成Model类(DB First)
采用EFCore逆向工具生成实体类。
模型类属性的设定有两种(DataAnnotation注解、FluentAPI)。
以下工具主要以DataAnnotation注解的形式实现。即,根据数据库的表,自动生成 C# 模型类,并将数据库的栏位属性,自动添加到对应模型类上的注解。
1. 安装 EF Core Power Tools 插件
打开VS > 延伸扩展 > 管理延伸扩展 > 搜索并安装 EF Core Power Tools(下载好后,需关闭VS才能安装。安装后,重启 VS)
2. 使用 EF Core Power Tools 插件生成模型类
右击专案,选择 EF Core Power Tools -> Reverse Engineer(反向工程)> 弹出的对话框中,选择数据库连接(也可自定义数据库,点击新增,根据需求选择数据库来源和输入数据库信息)> 点击确定后,新的对话框中选择要导出的表> 设定基础信息(DBContext名称等) > 勾选 Use DataAnnotation > 如有更多需求,可点击“进阶”> 点击确定,稍等几分钟。
3. 补充
若上述的选择数据库来源时,找不到想要的数据库来源,则需安装数据库对应的驱动(如postgre需要在NuGet中安装 Npgsql PostgreSQL Integration 插件)。
4. 所需插件如图所示
具体操作可参考另一篇文章:Backend - EF Core Power Tools(C# EFCore逆向工具)-CSDN博客
六、EF 仓储模式(类似于Django的ORM)
1. 创建Postgre仓储类
using System;
using System.Collections.Generic;
namespace ASPNetAPI.Models
{
public class PostgreMusicRepository : IMusicRepository
{
private readonly MusicDbContext _context;
public PostgreMusicRepository(MusicDbContext context)
{
this._context = context;
}
public Music CreateSong(Music music)
{
_context.Music.Add(music);
_context.SaveChanges();
return music;
}
public Music DeleteSong(int id)
{
Music music = _context.Music.Find(id);
if (music != null)
{
_context.Music.Remove(music);
_context.SaveChanges();
}
return music;
}
public IEnumerable<Music> GetAllSongs()
{
return _context.Music;
}
public Music GetSong(int id)
{
return _context.Music.Find(id);
}
public Music UpdateSong(Music updateMusic)
{
var music = _context.Music.Attach(updateMusic);
music.State = Microsoft.EntityFrameworkCore.EntityState.Modified;
_context.SaveChanges();
return updateMusic;
}
}
}
2.Programs.cs
using Microsoft.EntityFrameworkCore;
using ASPNetAPI.Models;
…
builder.Services.AddScoped<IMusicRepository, PostgreMusicRepository>();