項目介入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 "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();
}

這種每次都要刪庫😂,數據庫連接字符串一定要檢查好,以免誤刪別的庫.

還有另外一種方法

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

using (var scope = app.ApplicationServices.CreateScope())
{
    var context= scope.ServiceProvider.GetService<MyContext>();
    context.Database.EnsureCreated();//沒有則自動創建數據庫
}

第一次數據庫沒創建的時候,會自動創建數據庫

後續如果新增或修改了實體,先執行add-migrate createxxxTable命令,在執行Update-Database createxxxTable即可,會自動生成一個遷移表,記錄每一次的遷移。

 我們也可以將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);
    }
}

如有不足,望見諒!😊

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章