项目介入EF Core

目前.Net主流的ORM有SqlSugar、Entity Framework、Dapper,其它的我就不列举了。其实和Java那边ibatis相比,他们都比较轻量。之前用ibatis开发,真的很麻烦,而且在XML里面配置总感觉不太友好。

首先DbFirst模式,先在数据库建好表结构,然后在项目中生成实体。

引入包:Microsoft.EntityFrameworkCore.Tools、Microsoft.EntityFrameworkCore.Design、Pomelo.EntityFrameworkCore.MySql

写一个类继承于DbContext

复制代码
public class MyContext : DbContext
{
    public MyContext(DbContextOptions<MyContext> options) : base(options)
    {
    }

protected override void OnModelCreating(ModelBuilder modelBuilder) {  base.OnModelCreating(modelBuilder); } }
复制代码

在ConfigureServices方法中写入下面这句代码

services.AddDbContext<MyContext>(options => options.UseMySql(Configuration.GetConnectionString("dbconn")));

 在程序包管理控制台中输入命令:

Scaffold-DbContext(MySql) "server=localhost;user id=root;password=zhang.1122;port=3306;database=MicroservicesCoreDB;Charset=utf8;SslMode=None" "Pomelo.EntityFrameworkCore.MySql" -OutputDir Models -Context MyContext -UseDatabaseNames
Scaffold-DbContext(SqlServer) Scaffold-DbContext "Server=localhost;Database=test;User ID=sa;Password=123456;" Microsoft.EntityFrameworkCore.SqlServer -Context MyDbContext -OutputDir Aggregate -Tables user -UseDatabaseNames -DataAnnotations

-OutputDir Models表示生成的实体类放在Models文件夹下

-Context MyContext表示生成的数据库上下文对象的名称

-UseDatabaseNames表示完全按照数据的字段名和表名来生成实体对象,如果不加这个,默认会帕斯卡命名

后续如果新加了表,执行下面这个命令:

Scaffold-DbContext -Force "Server=localhost;port=3306;database=MicroservicesCoreDB;uid=root;pwd=zhang.1122;CharSet=utf8" -Provider "Pomelo.EntityFrameworkCore.MySql" -OutputDir Models -Tables report -UseDatabaseNames

-Tables report表示指定要生成的表,如果有多个表可用逗号分隔

按照上面那条命令,每次都会生成一个DbContext对象,默认命名为数据库名+Context.每次都要删除重新生成的上下文对象很麻烦,所以有更便捷的命令

Scaffold-DbContext "Server=localhost;port=3306;database=MicroservicesCoreDB;uid=root;pwd=zhang.1122;CharSet=utf8" -Provider "Pomelo.EntityFrameworkCore.MySql" -OutputDir Models -Context MyContext -UseDatabaseNames -Force

-Force命令可以同步数据库表结构,但是数据库删除了一个表,项目中对应的实体类还会存在,需要手动删除.

在执行命令之前,先重新生成一下项目,如果有报错的话,会生成不成功的.

第二种是CodeFirst模式

新建一个类DbInitialize,用于生成数据库及种子数据

复制代码
public class DbInitialize
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbcontext"></param>
        /// <param name="isDbInitialize"></param>
        public static void Initlialize(MyContext dbcontext, bool isDbInitialize)
        {
            if (isDbInitialize)
            {
                dbcontext.Database.EnsureDeleted();//删除
                dbcontext.Database.EnsureCreated();//再创建
                dbcontext.Department.Add(new Department
                {
                    department_name= "开发部",
                    department_num= "2020001",
                    dt= DateTime.Now,    remarks = "暂无",

}); dbcontext.SaveChanges();//持久化 } } }
复制代码

新建一个AppSettings类

public class AppSettings
{
    public bool IsDbInitialize { get; set; }
}

在appsettings.json中添加节点

  "AppSettings": {
    "IsDbInitialize": false//是否开启数据库创建
  }

在ConfigureServices注册

复制代码
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<MyContext>(options => options.UseMySql(Configuration.GetConnectionString("dbconn")));
    services.AddMvc(options =>
    {
        options.Filters.Add(typeof(GlobalExceptionFilter));
    });
    services.AddOptions();
    services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
}
复制代码

修改Configure方法

复制代码
public void Configure(IApplicationBuilder app, IHostingEnvironment env, MyContext context, IOptions<AppSettings> appSettings)
{
    app.UseAuthentication();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    DbInitialize.Initlialize(context, appSettings.Value.IsDbInitialize); //开启数据库脚本创建,谨慎!!!

    app.UseMvc();
}
复制代码

这种每次都要删库😂,数据库连接字符串一定要检查好,以免误删别的库.

还有另外一种方法

修改Configure方法,加入以下代码

using (var scope = app.ApplicationServices.CreateScope())
{
    var context= scope.ServiceProvider.GetService<MyContext>();
    context.Database.EnsureCreated();//没有则自动创建数据库
}

第一次数据库没创建的时候,会自动创建数据库

后续如果新增或修改了实体,先执行Add-Migration createxxxTable命令,在执行Update-Database createxxxTable即可,会自动生成一个迁移表,记录每一次的迁移。

 我们也可以将EnsureCreated()改为Migrate(),这样每次只需执行Add-migration createxxxTable命令即可,无需执行Update-Database createxxxTable命令.

using (var scope = app.ApplicationServices.CreateScope())
{
    var context = scope.ServiceProvider.GetService<DBContext>();
    context.Database.Migrate() ;//执行迁移
}

对了,我们可以在DBContext类的OnModelCreating方法中注册实体与数据库的映射关系,会根据映射关系生成对应的数据库表结构.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    #region 
    modelBuilder.ApplyConfiguration(new DepartmentEntityTypeConfiguration());
    #endregion
    base.OnModelCreating(modelBuilder);
}
复制代码
class DepartmentEntityTypeConfiguration : IEntityTypeConfiguration<Department>
{
    public void Configure(EntityTypeBuilder<Department> builder)
    {
        //定义主键
        builder.HasKey(p => p.Id);
        builder.ToTable("department");
        builder.Property(p => p.department_name).HasMaxLength(20);
        builder.Property(p => p.department_num).HasMaxLength(30);
        builder.Property(p => p.remarks).HasMaxLength(30);
        builder.Property(p => p.dt);
    }
}
复制代码

如有不足,望见谅!😊

 

作者:江北

出处:https://www.cnblogs.com/zhangnever/p/13571931.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

微信:CodeDoraemon

posted @   江北、  阅读(860)  评论(1编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
晓看天色暮看云