EFCore CodeFirst 適配數據庫


EF6中可以直接根據代碼模型生成數據庫Database.SetInitializer即可

在EFCore中如何實現呢?

這項功能放在了DatabaseFacade對象中,傳入數據庫上下文對象實例化到一個DatabaseFacade對象

可以看到DatabaseFacade有幾個方法:

 獲取所有遷移的migraion數據:GetMigrations

獲取待遷移的migration數據 :GetPendingMigrations

獲取已經操作的migration數據:GetAppliedMigrations

適配migration: Migrate

這中間有一個坑:efcore 貌似還不能根據模型生成數據庫,而是要先添加migrations的文件,然后才能適配數據庫

這里我添加了一個XXXX字段,按照正常的流程:我們需要執行命令:

dotnet ef migrations add addxxxxxx

dotnet ef database update

EFCore中的自動適配數據庫的前提是添加好 新增變量的migrations文件,實際上只是efcore只幫助了我們實現了dotnet ef database update的操作

首先先操作下:dotnet ef migrations add addxxxxxx

這里我寫了一個簡單的中間件來說明下:

通過注冊服務,添加usermap引用

 /// <summary>
        /// liyouming add 20180508
        /// </summary>
        /// <typeparam name="T">(context)上下文對象</typeparam>
        /// <param name="service">擴展服務</param>
        /// <param name="optionsAction">配置</param>
        /// <returns></returns>
        public static IServiceCollection AddEFMigrations<T>(this IServiceCollection service, Action<DbContextOptionsBuilder> optionsAction) where T : DbContext
        {
            service.AddDbContext<T>(optionsAction);
            var serviceProvider = service.BuildServiceProvider();
            service.AddSingleton<IEFMigrationsContext>(new EFMigrationsContext(serviceProvider.GetRequiredService(typeof(T)) as DbContext));
            return service;
        }

這里我們需要指導上下文對象T,並將該對象放到自定義的服務 IEFMigrationsContext 去處理下

然后擴展下IApplicationBuilder

public static IApplicationBuilder UseEFMigraions(
           this IApplicationBuilder builder,string pathstring)
        {
            builder.Map(new Microsoft.AspNetCore.Http.PathString(pathstring), app => {
                app.UseMiddleware<EFMigrationsMiddleware>(pathstring);
            });
            return builder;
        }

比較簡單,需要map下地址,當我們訪問的時候進入到固定頁面操作

 public class EFMigrationsMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly string _pathstring;
        private IEFMigrationsContext _migrationsContext;

        public EFMigrationsMiddleware(RequestDelegate next, string pathstring, IEFMigrationsContext migrationsContext)
        {
            if (next == null)
            {
                throw new Exception(nameof(next));
            }
            _next = next;
            _pathstring = pathstring;
            _migrationsContext = migrationsContext;

        }

        public async Task Invoke(HttpContext context)
        {
            if (context.Request.PathBase == _pathstring)
            {
                var list = _migrationsContext.GetPendingMigrations();
                _migrationsContext.AutoMigration();
                string strli = string.Empty;
                foreach (var item in list)
                {
                    strli += "<li>" + item + "</li>";
                }
                await context.Response.WriteAsync("<html><body><ul>" + strli + "</ul></body></html>");
            }
            else
            {
                await _next(context);
            }
            return;





        }
    }

下面直接實現接口方法就ok了,存在待更新的migrations就執行更新

public void AutoMigration()
        {
            if (databaseFacade.GetPendingMigrations().Any())
            {
                //執行遷移
                databaseFacade.Migrate();
            }
           
        }

下面來說下使用方式:跟原有的dbcontext使用方式一樣,配置好你的上下文對象配置

注冊服務:

 services.AddEFMigrations<UserDbContext>(optionsBuilder =>
            {
                var _userappsetting = Configuration.Get<UserAppSetting>();
                if (_userappsetting == null)
                {
                    throw new Exception("數據庫連接字符串未配置");
                }
                switch (_userappsetting.DbType)
                {
                    case 1:

                        optionsBuilder.UseSqlServer(_userappsetting.UserConnectionString, sqlserver =>
                        {
                            sqlserver.MigrationsAssembly(_migrationAssablyName);
                            sqlserver.UseRelationalNulls();
                            sqlserver.UseRowNumberForPaging();

                        });
                        break;
                    case 2:
                        optionsBuilder.UseMySQL(_userappsetting.UserConnectionString, mysql =>
                        {
                            mysql.MigrationsAssembly(_migrationAssablyName);
                            mysql.UseRelationalNulls();
                        });
                        break;
                    default:
                        optionsBuilder.UseSqlServer(_userappsetting.UserConnectionString, sqlserver =>
                        {
                            sqlserver.MigrationsAssembly(_migrationAssablyName);
                            sqlserver.UseRelationalNulls();
                            sqlserver.UseRowNumberForPaging();
                        });
                        break;
                }
            });
AddEFMigrations

添加Configure

 app.UseEFMigraions("/Migrations");

下面訪問下:/Migrations ,這里上面的代碼中我先獲取了待更新的migraions 方便驗證,這里可以看到待驗證的migraions是我新添加 addxxxxxxx

下面我們來檢查數據生成情況: 已經生成了 XXXXX字段

 

 

 如果能不操作dotnet ef migrations add addxxxxxx就好了,感覺還是有點雞肋~~~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM