25

项目介入EF Core

 3 years ago
source link: http://www.cnblogs.com/zhangnever/p/13571931.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

目前.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 "server=localhost;user id=root;password=zhang.1122;port=3306;database=MicroservicesCoreDB;Charset=utf8;SslMode=None" "Pomelo.EntityFrameworkCore.MySql" -OutputDir Models -Context MyContext -UseDatabaseNames

-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();
}

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

还有另外一种方法

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

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

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

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

263Efmq.png!mobile

我们也可以将EnsureCreated()改为Migrate(),这样每次只需执行add-migrate 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);
    }
}

如有不足,望见谅!:blush:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK