EF Core 2.0 Add-Migraion 出現無法建立 DbContext 錯誤

傳統的設定再執行 Add-Migration 會出現錯誤:

PM> Add-Migration InitialCreation

Unable to create an object of type ‘OrderContext’. Add an implementation of ‘IDesignTimeDbContextFactory<OrderContext>’ to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.

這是因為 EF Core 2.0 有改變 Tools 的作法,在 Asp.net core 最佳的解法是:

WebHost.CreateDefaultBuilder(args)

如果是 Console program,可以用 emtpy constructor 的方式:

public class OrderContext : DbContext
{
    public OrderContext() { }
    public OrderContext(DbContextOptions<OrderContext> options) : base(options) { }
    public DbSet<OrderProcess> OrderProcesses { get; set; }
 
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=(localdb)\MSSQLLocalDB;Database=Msmtest;Trusted_Connection=True;");
    }
}

重點在於 OnConfiguring 加上指定的 SqlServer connection。一旦產生 Migration 之後,就可以將 empty constructor comment 掉(因為可能會影響程式的正常邏輯)。

如果有多個 Context,可以在 Add-migration & Update-Database 中指定哪一個要進行更新:

Add-Migration Initial -Context LhcPlatformContext

Update-Database -Context LhcPlatformContext

請注意,如果使用 Seeding the Database 進行資料庫 seeding,那要注意必須要先拿掉 seed data 段落之後才會正確執行,否則會出現: “An error occurred while calling method ‘BuildWebHost’ on class ‘Program’. Continuing without the application service provider.

這個原因是因為我們都是使用 Development 環境在執行,因此會進入到 Seed() 函數,但在 Add-migration 時候實際上並沒有對應的資料庫表格,因此在執行 Seed() 會造成錯誤。

解學方案就是透過檢查 Migration 是否都已經執行後,在進行 Seed,。詳細作法參閱:How to seed your EF Core database

重點在於檢查是否都已經執行 migration:

using (var scope = app.ApplicationServices.CreateScope())
{
    var services = scope.ServiceProvider;
    if (!services.GetService<LhcPlatformContext>().AllMigrationsApplied())
    {
        var context = services.GetRequiredService<LhcPlatformContext>();
        context.Database.Migrate();
        LhcSeedData.Initializer(context);
    }
}

其中 AllMigrationsApplied() 如下:

public static bool AllMigrationsApplied(this DbContext context)
{
    var applied = context.GetService<IHistoryRepository>()
        .GetAppliedMigrations()
        .Select(m => m.MigrationId);
 
    var total = context.GetService<IMigrationsAssembly>()
        .Migrations
        .Select(m => m.Key);
 
    return !total.Except(applied).Any();
}

 

 

VS 2017 偵錯時候發生無法連結到Web伺服器 IIS Express

VS 2017 在執行 unit test 發生奇怪的問題,重新啟動後,按下 F5 偵錯,居然發生:

關機再開也沒有用,只好查網路說明了。最常見的說明:

除 .vs/ 目錄,或者重新修改 port 、或者
有人建議刪除 %userprofile%/Documents/IISExpress/config 資料夾,重啟 Visual Studio

但以上我測試結果都不行。,問題一樣發生。查了半天 Stackoverflow 有一篇文章 說可以將 Internet connection sharing 關閉:

果然用這個方式就可以順利解決問題。同時附註:一旦問題排除後,再重新啟動也是沒問題的。至於是麼原因那就只有天知道了…。

整合 Asp.net Core & Angular Cli 混合開發模式

Angular Cli 可以說是目前使用 Angular 2 以上的開發主要啟動方案。透過簡單的命令頁可以快速依據設定加入 component 的內容,降低維護基本的 import 項目的複雜度。可以參考:基本的 Angular Cli 說明

但對於使用 aps.net core 開發的人員而言,以下說明如何將 angular cli 整合到專案內,同時可以獲得兩者的便利性。

  • 首先,在專案目錄下執行 ng new(如果不知道 angular cli command 請參閱上面的說明連結),執行完畢後會產生 angular cli 預設的 source code folder:

這裡包含完整的啟動程式架構,可以透過瀏覽 index.html 進行操作。

  • 將產生的檔案移動到 Asp.net Core 的專案下。要複製兩種內容:

angular 執行程式:指定 angular source code 放入到 任意的指定目錄下(例如:ClientApp\ ),這裡的 source code 就是指 src\ 目錄下的所有內容:

angular cli 的組態設定檔案:就是指跟 src\ 目錄平行的檔案,複製到專案的根目錄下(與 Startup.cs 平行的路徑):

  • 修改變更路徑後的 angular cli 相關組態設定

tsconfig.json 用來編譯 typescript to javascript,修改:

1. outDir 改為 asp.net wwwroot: “outDir”./wwwroot/clientapp/out-tsc”

2. include 改為前面所設定的程式目錄(例如: ClientApp\)

修改 angular-cli.json,同樣將 outDir 改為 wwwroot 目錄

完成相關設定後,就可以在專案目錄下執行 angular cli 了。

 

Visual Studio 2017 預設文件編碼改為 UTF-8

有些時候在撰寫程式時,會看到最終結果是亂碼:

但在 VS 2017 中的編輯器顯示是正常的:

<button class="btn btn-primary" type="submit"
        [disabled]="form.$pristine || form.$invalid" [faIcon]="'fa-save'">
    存檔
</button>
<button class="btn btn-warning" (click)="cancel(form)" type="button" [faIcon]="'fa-undo'">
    取消

這時可能就是編碼問題了,因為網頁預設採用 utf-8,但實際上VS用 big5 儲存。

修改方向如下:

1. 設定 VS 的編輯選項,將【無法以字碼頁儲存資料時,將文件儲存為 unicode】:

2. 已經寫的文件,可以透過文字檔檔編輯方式改為 utf-8,或者透過另存方式指定編碼: