前回めでたくUbuntuでASP.NET Core + EF Coreが動いたので、次はスキーマ変更を試してみます。

フィールドを追加

試しにフィールド”Description”を追加してみます。

1
2
3
4
5
6
7
8
public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
        public string Description { get; set; }    //追加
        public int Rating { get; set; }
        public List<Post> Posts { get; set; }
    }

まずはPMCで開発環境からスキーマアップデート

1
2
3
4
PM> Add-Migration AddDescriptionField
To undo this action, use Remove-Migration.
PM> Update-Database
Done.

pgAdminでフィールド増えてるのを確認できます。

本番環境アップデート

デプロイ

dotnet publish –configuration Release -r ubuntu.16.04-x64

dotnet ef migrations script

吐き出されるSQLはMigrationIdのチェックはしてくれないみたいなので、

既に実行済みのMigration以下を選択して実行します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
....
CREATE INDEX "IX_Posts_BlogId" ON "Posts" ("BlogId");

INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20170615065858_InitialCreate', '1.1.2');

# これ以下を実行
ALTER TABLE "Blogs" ADD "Description" text;

INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20170619040546_AddDescriptionField', '1.1.2');

ちょっと面倒ですね。

Auto Migration

いちいち手でSQLは面倒なので、アプリのスタート時にAuto Migrationするようにします。

Startup.csのConfigureにcontext.Database.Migrate()を呼ぶ処理を追加。

1
2
3
4
5
6
7
8
9
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
....
            using (var context = app.ApplicationServices.GetService<BloggingContext>()) {
                context.Database.Migrate();
            }
....
        }

試しにPostにSlugフィールドを追加してみる。

1
2
3
4
5
6
public class Post
    {
....
        public string Slug { get; set; }  //追加
....
    }
1
PM> Add-Migration AddSlugField

実行してフィールドが増えればOK

実行時出力で

1
2
3
4
5
6
7
info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      ALTER TABLE "Posts" ADD "Slug" text;
info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
      VALUES ('20170619070402_AddSlugField', '1.1.2');

なんかやってる様子が確認できます。

普通に動く

EFがlinux+postgresで普通に動きます。

感動〜

次はNginxとコラボしてみます。