Entity Framework Core (EF Core) を使ってSQL Server (LocalDB) に接続し、DBを生成したりCRUD操作をする方法を解説します。
※直接SQLでデータを操作する方法(ADO.NET)については以下を参照してください。
環境
- Visual Studio 2022
- .NET 8
プロジェクトの作成
Visual Studioで新しいプロジェクトを作成します。今回はコンソールアプリを使って解説します。
必要なパッケージのインストール
まずEF Coreを使うために必要なパッケージをインストールします。
NuGetパッケージマネージャーなどから以下の2つのパッケージをインストールしてください。
※パッケージのバージョンはお使いの.NETのバージョン(ターゲットフレームワーク)に合わせるようにしてください(.NET 6ならバージョン6.x系など)
EntityとDbContextクラスの用意
Todoを管理する簡単なアプリケーションを作成します。
ここではDBのテーブルに対応するEntityクラスと、DBとEntityクラスの橋渡しを行うDbContextクラスを作成しましょう。
プロジェクト直下に以下の2つのクラスを作成してください。
まずTodoエンティティを定義します。
ID(主キー)、Todo名、完了フラグを保持するテーブルです。
namespace SQLServerCurdSample
{
internal class Todo
{
public int Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
}
次にDbContextクラスです。
「UseSqlServer」の後にSQL Server Local DBの接続文字列を記載します。
using Microsoft.EntityFrameworkCore;
namespace SQLServerCurdSample
{
internal class TodoContext : DbContext
{
public DbSet<Todo> Todos { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(
@"Server=(localdb)\mssqllocaldb;Database=Sample;Trusted_Connection=True");
}
}
}
DatabaseにはSampleという名前を指定していますが、任意の名前で大丈夫です。マイグレーション時にここで指定した名前のDBが自動で作成されます。
マイグレーション
マイグレーションを行うことで、作成したEntityクラスに対応したテーブルがLocal DBに作成されます。
「ツール」→「NuGetパッケージマネージャー」→「パッケージマネージャーコンソール」でコンソールを開き、以下のコマンドを実行してみましょう。
Add-Migration InitialCreate
Update-Database
これらのコマンドで行われることは次の通りです。
- Add-Migrationコマンド:変更内容が記録されたマイグレーションファイルを作成する
※Initial Createと記載している部分は任意です。変更内容がわかるようなメッセージを記載します。 - Update-Databaseコマンド:マイグレーションファイルの内容をDBに反映する
実行後、「Done」と表示されればマイグレーション成功です。
Visual StudioのSQL Server オブジェクトエクスプローラー(上部メニューの「表示」から選択可能)などでLocalDBを開くと、テーブルが作成されていることが確認できます。
また、プロジェクト直下にMigrationsフォルダが作成されています。
この中には今回のマイグレーション内容等が記載されたファイルが格納されています。
CRUD操作の実装
それでは、作成されたテーブルに対してCRUD操作を行うプログラムを実装しましょう。
今回はサンプルコードのため全てProgram.cs(最上位レベルのステートメントを使用)に記載しています。
using SQLServerCurdSample;
using Microsoft.EntityFrameworkCore;
using (var context = new TodoContext())
{
// ①登録
context.Todos.Add(new Todo { Name = "C#学習", IsComplete = false });
context.Todos.Add(new Todo { Name = "筋トレ", IsComplete = false });
context.Todos.Add(new Todo { Name = "映画鑑賞", IsComplete = false });
await context.SaveChangesAsync();
// ②1件取得(Idが最も小さいレコード)
var todo = await context.Todos.OrderBy(t => t.Id).FirstAsync();
// ③更新
todo.IsComplete = true;
await context.SaveChangesAsync();
// ④全件取得
var todos = await context.Todos.ToListAsync();
todos.ForEach(t => Console.WriteLine($"④ Id:{t.Id}, Name:{t.Name} IsComplete : {t.IsComplete}"));
// ⑤全件削除
context.RemoveRange(todos);
await context.SaveChangesAsync();
}
Console.ReadLine();
簡単に処理内容を説明します。
- まずTodoアイテムを3つTodosに追加しています。IDは自動採番の設定になっているので指定する必要はありません。SaveChangesAsyncを呼び出すことでINSERT文が実行されます。
- Todosテーブルのデータを昇順にソートした後に、先頭の1レコードを取得しています。
- ②で取得したデータの完了フラグをtrueに変更後、SaveChangesAsyncを呼び出してUPDATE文を実行しています。
- ToListAsyncでTodosテーブルから全件を取得し、ForEachでコンソールにデータの中身を出力しています。
- RemoveRangeに④で取得したデータを渡して取り除いた後に、SaveChangesAsyncを呼び出してDELETE文を実行しています。なお、1件だけ削除したい場合はRemoveメソッドに1つのtodoを渡します。
デバッグ実行すると、④の全件取得結果がコンソール上に表示されます。
※画像は何度か実行したものなのでIdが大きくなっています。
上記のコードでは最後に登録したデータを全て削除しているため、DB上ではデータを確認できません。確認したい場合は⑤の削除処理をコメントアウトしてください。
ちなみにEF Core 7.0以降であれば、UpdateとDeleteの処理を以下のように記述できます。
条件に該当する複数のレコードを一括更新/削除する場合に便利です。
// 完了フラグがfalseのレコードを全てtrueに更新
context.Todos.Where(t => !t.IsComplete).ExecuteUpdate(s => s.SetProperty(t => t.IsComplete, true));
// 完了フラグがtrueのレコードを全て削除
await context.Todos.Where(t => t.IsComplete).ExecuteDeleteAsync();
(参考)