【C#】Asp.net Core EFでSqlServerに対しマイグレーションをする方法

みなさんこんにちは!!これまでFirestoreを使って開発をしていましたが、どうしてもNoSqlというものが好きになれずAsp.Netに戻ってきました。

いや。ね?NoSqlとやらはすごくしっかりとできていると思うんですよ。

RDBみたいにトランザクションとか一応あるし、リレーション的なものもあるし慣れれば使い勝手良いんだろうなーーーと思いました。

でも私はバックエンド出身なので、どうしてもRDBを使いたいのです!

フロント側よりもバック側を作っているときの方が楽しいのです!

ってことでAsp.Netに戻ってきたのですが、今回久々に触ったためAsp.Net Core EFでどうやってSqlServerと接続するんだっけ?マイグレーションってどうやってやるんだっけ?ってなったので、その備忘録って感じで書いていきたいと思います。

目次

フェーズ1:プロジェクト側

💡 EF Core vs EF6 で Migration コマンドが違う件は別記事 ASP.NET MVC ORM 3択 で EF6 編もまとめてます。

プロジェクトを作っていく

今回作っていくのはAsp.net Core3.1のApiってことで早速作っていきましょう!

Apiを選択する

Nugetでライブラリを追加する

続いてNugetパッケージの導入です。

ツール⇒NuGetパッケージマネージャー⇒ソリューションのNuGetパッケージの管理をクリック

すると下記のような画面が開くと思います。

なので参照を押して下記ライブラリを探しましょう

  • Microsoft.EntityFrameworkCore.SqlServer
検索窓で文字列を入れてそのまま検索をすれば一番上に出てくる
チェックを入れて、インストールを押す。
依存関係から追加されているのを確認できる。

Modelを作る

次にめっちゃ簡単でいいからModelを作る。

今回はID、Nameを持ったUserModelを定義する

まずはModelsというフォルダを作る。

その中にUserというモデルを定義する

namespace sqlserver_connection_demo.Models
{
    public class User
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}

Contextを作る

次に先ほど作ったModelsフォルダに、Contextを作っていく。

実際にEFを使っていく際はDBにこのContextを介してアクセスするという使い方になると思われる。

コードはこんな感じ!

using Microsoft.EntityFrameworkCore;

namespace sqlserver_connection_demo.Models { public class DemoContext : DbContext { public DemoContext(DbContextOptions<DemoContext> opt):base(opt) {

    }
    
    // Modelが増えたらこんな感じで増やしていく。
    public DbSet&lt;User&gt; Users { get; set; }
}

}

Contextは基本的にDBとの間に立ってくれるので、Modelが増えたらそれを都度この中に入れていく必要がある。

またDBの初期データなどを入れていくときもこの中に書いていくらしい。

Start.csを修正する

ここまで来たらStart.csを一旦更新する。

全体のコードはこんな感じ

namespace sqlserver_connection_demo
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        private SqlConnectionStringBuilder stringBuilder = new SqlConnectionStringBuilder()
        {
            InitialCatalog = "DemoDB",
            DataSource = "localhost",
            UserID = "sa",
            Password = "sa"
        };
        public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddDbContext&lt;DemoContext&gt;(opt =&gt;
        {
            opt.UseSqlServer(stringBuilder.ToString())
        })
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =&gt;
        {
            endpoints.MapControllers();
        });
    }
}

}

ここで重要なのはハイライトを付けている箇所である。

        private SqlConnectionStringBuilder stringBuilder = new SqlConnectionStringBuilder()
        {
            InitialCatalog = "DemoDB",
            DataSource = "localhost",
            UserID = "sa",
            Password = "sa"
        };

このコードはSqlServerに接続する際に必要な接続文字列を自動で生成してくれるSqlConnectionStringBuilderというクラスのインスタンスを作っている。

  • InitialCatalogは接続するDBの名前
  • DataSourceは接続するDBがどこにあるのか?

この2点を覚えて入れば良いと思う。

            services.AddDbContext<DemoContext>(opt =>
            {
                opt.UseSqlServer(stringBuilder.ToString());
            });

で、ここでさっき追加したDemoContextを追加して、Sqlserverを使うという宣言をしておく。

スキャフォールドしたControllerを作る

でここでスキャフォールドしたControllerを作っていくが、ここで作る目的は一つ。

初回のスキャフォールドでマイグレーション実行に必要なライブラリを自動でインストールしてくれるという部分。

とりあえずやっていく。

Controllerのフォルダ上で右クリックをして、追加⇒新規スキャフォールディングアイテムをクリック

でEntity Frameworkを使用したアクションがあるAPIコントローラーを選択

でさっき作ったUserModelとDemoContextを選択する。

コントローラー名は自動でModel名の複数形になったものが名前として設定される。

これでOKを押すと、勝手にビルドが走って必要なライブラリが追加される

依存関係にはこんな感じでライブラリが追加されている。

またこんな感じでCRUD機能を持ったControllerが作られている。

ここで一旦プログラム側でやる処理は終わり。

フェーズ2:Sqlserver側

次はSqlserver側でやる作業になる。

といってもDB作るだけ。

SqlServerにDBを作る

他の仕事で使っているDBがあるので、赤で塗りつぶしている

新しいデータベースをクリックして出てきたダイアログにさっきSqlConnectionStringBuilderで指定したInitialCatalogのDB名を入れる。

すればこんな感じでDBが作られる

フェーズ3:コマンド実行

で最後にVisualStudio側でコマンドの実行

パッケージマネージャーコンソールでコマンドを打っていく

もしパッケージマネージャーコンソールがどこにも見当たらない場合は、表示⇒その他のウインドウから表示できる。

まず打っていくコマンドは下記。

PM> enable-migrations

するとこんな感じでマイグレーションをする準備ができた。

次に実行するコマンドは下記。

PM> Add-Migration initial-migration

するとこんな感じでコマンドが通ったことが確認できる。

同時に初回マイグレーションであれば、下記のようにMigrationsフォルダが追加されて、中に実行予定のMigrationファイルが作られる

これが自動マイグレーションで作られたファイルの中身

で最後に上記のマイグレーションの内容をDBに反映させていきたい。

なので、下記コマンドを実行する

PM> update-database

すると、下記のような感じになってコマンドが通ったことがわかる。

SqlServer側を見てみるとこんな感じでTableが追加されている。

💡 補足: 業務系の現場でよくハマるパターン

俺もこの EF Core + SqlServer マイグレーション、 業務でハマってきたところを3つ並べておきます。

① 接続文字列を本番/Dev で間違える事故

appsettings.json と appsettings.Development.json で接続文字列を分けるが、 環境変数読み込みが優先順位で逆転すると本番DBに Dev のマイグレーションが流れる致命事故。 ASPNETCORE_ENVIRONMENT を必ず確認してから dotnet ef database update を打つ。

② Add-Migration の AutoIncludeDbContext で複数 Context 競合

DbContext が2つ以上あるプロジェクトで Add-Migration Init すると「Context が複数」エラー。 --context MyDbContext オプション必須。 業務系で読み書き分離する時に頻発。

③ Update-Database で本番接続事故

VS の Package Manager Console で Update-Database 叩く時、 デフォルト接続が本番文字列だと一発で本番DBに反映される。 接続文字列を毎回声に出して確認するレベルで安全側に倒す。

❓ よくある質問

Q1. Migration ファイルが大きくなりすぎた場合の対処は?

A. 不要な Migration を Squash (統合) する。 EF Core 7+ なら dotnet ef migrations script で SQL 化して整理可能。 過去 Migration を消す時は production の __EFMigrationsHistory テーブルとの整合性が崩れないか確認。

Q2. Code First と Database First どっちがいい?

A. 新規プロジェクトなら Code First (EF Core 推奨)。 既存 DB を C# 化するなら Database First で Scaffold-DbContext。 業務系の保守は Database First で入って徐々に Code First 化が現実解。

Q3. Migration で生成された SQL を本番で実行する手順は?

A. dotnet ef migrations script FromMigration ToMigration -o migration.sql で SQL ファイル生成 → DBA に渡して SSMS で実行。 直接 database update を本番で打つのはNG (権限分離の基本)。

Q4. SeedData の管理はどうしてる?

A. OnModelCreatingHasData() 使うのが標準。 ただし複雑な seed (条件分岐含む) は Migration の Up() 内で migrationBuilder.Sql(...) を直接書く方が柔軟。

Q5. ステージング環境で migration を試す方法は?

A. 本番 DB のスナップショットを取って Staging に restore → dotnet ef database update --connection "Staging接続文字列" で当てる。 1回試して問題なければ本番反映。

📚 関連記事

執筆者

バイブス父さん — 業務 SE 7 年 (正社員 2 / フリーランス 5)。 現職は SEO 直轄部の AI アドバイザー兼 PL、 副業で中小 SIer の CTO。 SES 複数社・フリーランスエージェント複数経由の経験ベースで「業務 SE 視点」 の技術 + キャリア記事を書いています。

🐦 X: @hiro_progra0524 (日々の現場メモ更新中)
📝 About Me で経歴詳細を見る

この記事が気に入ったら
いいねしてね!

どんどんシェア待ってるぜ!!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次