1. 環境
2. Entity Framework Coreとは
.NET用のORMです。2016年中頃に.NET Coreへ導入されました。
Entity Frameworkを完全に書き換えたものなので、パフォーマンス面でも大幅に改善されています。もちろんLINQ対応しています。
ざっくり言ってしまうと通常記述しなければいけないコードを簡略化できる便利な仕組みです。
※参考 - Entity Framework Core の概要
サクッと行けるのでやっていきます。
今回作成したプログラムはGitHubにあげています。
3. プロジェクトの準備
.NETもしっかりCLIがあるのでコマンドを叩いて準備していきます。まずはディレクトリを作成します。
❯❯❯ mkdir DatabaseTest ❯❯❯ cd DatabaseTest/
次はソリューションファイルとプロジェクトを作成します。
DatabaseTest ❯❯❯ dotnet new sln
DatabaseTest ❯❯❯ dotnet new webapi -n Api
どのようなテンプレートを扱えるか忘れた場合、以下のコマンドを打つと良いです。
DatabaseTest ❯❯❯ dotnet new -l
とりあえず困ったらdotnet -h
でヘルプを見ましょう。
ソリューションにプロジェクトを追加します。
DatabaseTest ❯❯❯ dotnet sln add Api
4. VS Codeで作業していく
ここからはVS Codeで進めていきます。
まず、以下のNuGet Packageをインストールします。
※Nuget Galleryの拡張機能がインストールされている前提です。
Nuget Gallaryを開くと以下のような画面になるのでプロジェクトを選択し、インストールします。
4.1. モデル用クラスを追加
実際は責務を分けるために別プロジェクトで作成するのが良いですが、今回はApiプロジェクトにまとめていきます。
// DatabaseTest/Api/Model/User.cs public class User { public Guid Id { get; set; } public string Name { get; set; } public int Age { get; set; } public double Height { get; set; } public double Weight { get; set; } }
4.2. DbContextを継承した派生クラスを作成
DataContext
のコンストラクタがないとエラーを吐くので忘れずに追加しましょう。VS Codeだと⌘
.
のショートカットキーを使うとサクッと生成出来ます。
ちなみに変数名がテーブル名となり、この例だとUsers
というテーブルが最終的に作成されます。
// DatabaseTest/Api/DataService/DataContext.cs public class DataContext : DbContext { public DataContext(DbContextOptions options) : base(options) { } public DbSet<User> Users { get; set; } }
4.3. Startup.csの修正
以下の通り、Startup.cs
を修正してSQLiteの依存関係を追加します。
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Api", Version = "v1" }); }); // 追加 services.AddDbContext<DataContext>(opt => { opt.UseSqlite(Configuration.GetConnectionString("DefaultConnections")); }); }
Api/appsettings.Development.json
に接続文字列を追加します。
{ "ConnectionStrings": { "DefaultConnection": "Data source=database.db" } }
ついでにApi/Properties/launchSettings.json
も修正します。アプリケーション実行時に毎回ブラウザが起動するのは煩わしいので、対象プロジェクト(ここではApi)に記述されているlaunchBrowser
をfalse
にし、ブラウザ起動を抑止します。
{ "Api": { "commandName": "Project", "dotnetRunMessages": "true", "launchBrowser": false, "launchUrl": "swagger", "applicationUrl": "https://localhost:5001;http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } }
データを投入するクラスを作成します。
// Api/DataService/Seed.cs public static async Task UserData(DataContext context) { if(context.Users.Any()) return; var users = new List<User> { new User { Name = "Suzuki", Age = 20, Height = 172.1, Weight = 60.4 }, new User { Name = "Tanaka", Age = 30, Height = 182.5, Weight = 72.4 }, new User { Name = "Yamada", Age = 25, Height = 160.5, Weight = 48.9 }, new User { Name = "Sato", Age = 22, Height = 175.6, Weight = 65.2 } }; await context.Users.AddRangeAsync(users); await context.SaveChangesAsync(); }
dotnet-ef
がインストールされているか確認します。
DatabaseTest ❯❯❯ dotnet tool list --global パッケージ ID バージョン コマンド ----------------------------------- dotnet-ef 5.0.4 dotnet-ef
dotnet-ef
が表示されていなければインストールしましょう。もし、既にインストールされていれば以下のコマンドはスキップしてOKです。
DatabaseTest ❯❯❯ dotnet tool install --global dotnet-ef
マイグレーションします。
DatabaseTest ❯❯❯ dotnet ef migrations add InitialCreate -s Api/
ここまで来たらdotnet ef database update
のコマンドを打つことでデータベースが作成出来ますが、今回はアプリケーション実行時にデータベースの作成、シードデータを投入したいので最後にProgram.cs
のMain
メソッドを修正します。
// Api/Program.cs public static async Task Main(string[] args) { var host = CreateHostBuilder(args).Build(); // C# 8.0以降 using var scope = host.Services.CreateScope(); var services = scope.ServiceProvider; try { // GetServiceでnullチェックでも良い var context = services.GetRequiredService<DataContext>(); // 待機しないと怒られます await context.Database.MigrateAsync(); // シードデータ投入 await Seed.UserData(context); } catch (Exception e) { var logger = services.GetRequiredService<ILogger<Program>>(); logger.LogError(e, "migrateでエラーが発生しました。"); } await host.RunAsync(); }
ようやくアプリケーションの実行です。dotnet watch run
としているのはファイルの更新を検出し、自動的にビルド、アプリケーション起動が出来るので常用しています。
DatabaseTest ❯❯❯ cd Api/ Api ❯❯❯ dotnet watch run
実行するとターミナルにログが出力されます。内容を見るとCREATE TABLE
やINSERT
が実行されているのがわかります。appsettings.Development.json
で設定したdatabase.db
ファイルが作成されているので確認します。
VS CodeのコマンドパレットからSQLiteを選択します。
database.db
を選択します。
SQLite Explorerが表示されるのでUsers
テーブルが作成されていることが確認出来ました。最後にデータが投入されているか確認します。
問題なく作成されています。良かった良かった。
5. まとめ
Visual Studioからポチポチとやってしまう事が多かったので、CLIとVS Codeで作成するケースを書き起こしてみました。
今回はモデルに変更を加えた後にどういった手順を踏むかについては触れていませんが、ゴリゴリとプログラムを書くことなく、データベースとテーブルの作成、シードデータの投入が出来ました。
なんて楽なんだ。あとはController
にDataContext
を注入して、LINQで書いていく感じです。公式にもチュートリアルがあるので、以下を参考にするのも良いです。
こちらを見る限り、データ操作だとORMに関してはEntity Framework CoreとDapperが書かれているので、ORMを使った場合はこの2択なのかな?というところです。
2016年の記事ですが、以下でパフォーマンスのデータを提供している記事もありました。Dapperも今度試します。