この記事のコードは .NET 10(C# 14)・EF Core で動作を確認した内容です。バージョンでコマンドや書き方が変わることがあるので、詰まったときは Microsoft Learn の公式ドキュメントもあわせて確認してください。
「SQLをあまり書かずに、C#のコードだけでデータベースを操作したい」。そんなときに使うのが Entity Framework Core(EF Core) です。Microsoft 純正のフルORMで、テーブル定義(スキーマ)の管理まで面倒を見てくれます。
この記事では、SQLite を例に、EF Core の導入からマイグレーション、LINQ を使ったCRUD(追加・取得・更新・削除)までを、手を動かしながら進めます。
EF Coreとは(Dapperとの違い)
EF Core は「オブジェクトとテーブルを対応づけて、SQLをほぼ書かずにDBを扱う」ためのライブラリです。C#のクラスがテーブルに、プロパティが列に対応します。
- SQLを書かなくていい:
db.Books.Where(...)のようにLINQで書くと、EF Coreが裏でSQLに翻訳して実行する - マイグレーション:C#のモデルを変えると、それに合わせてテーブル定義を更新できる
- 変更追跡:取ってきたオブジェクトを書き換えて
SaveChanges()を呼ぶだけで、差分をUPDATEしてくれる
一方、Dapper は「自分で書いたSQLを実行するだけ」の軽量ORMでした。ざっくり言えば、楽をしたい・スキーマも任せたいならEF Core、SQLを握りたい・軽さ重視ならDapperです。
準備:プロジェクトとパッケージ
コンソールアプリを作り、SQLite用のEF Coreプロバイダーを入れます。
dotnet new console -o EfCoreSample
cd EfCoreSample
dotnet add package Microsoft.EntityFrameworkCore.Sqliteマイグレーションを使うために、CLIツールと設計用パッケージも入れておきます。
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.DesignモデルとDbContextを定義する
EF Core では、テーブルに対応する エンティティクラス と、DBとのやり取りの窓口になる DbContext を用意します。
using Microsoft.EntityFrameworkCore;
// テーブルに対応するクラス
public class Book
{
public int Id { get; set; }
public string Title { get; set; } = "";
public int Price { get; set; }
}
// DBとのやり取りの窓口
public class AppDbContext : DbContext
{
public DbSet<Book> Books { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=books.db");
}DbSet<Book> が「Book テーブル」に相当します。OnConfiguring で接続先(ここでは books.db というSQLiteファイル)を指定しています。
マイグレーションでテーブルを作る
モデルを書いたら、その定義からテーブルを自動生成します。これがマイグレーションです。
dotnet ef migrations add InitialCreate
dotnet ef database updatemigrations add… 現在のモデルとの差分から、テーブルを作る「設計図」を生成するdatabase update… その設計図を実際のデータベースに適用する
以降、モデルにプロパティを足したら、また migrations add 変更名 → database update を繰り返すだけで、テーブル定義を追従させられます。SQLの ALTER TABLE を手書きしなくていいのが大きな利点です。
CRUD:LINQで操作する
Program.cs を次のように書き換えると、一通りの操作が試せます。EF Coreは非同期メソッド(SaveChangesAsync など)が用意されているので、そちらを使うのがおすすめです。
using Microsoft.EntityFrameworkCore;
using var db = new AppDbContext();
// Create(追加)
db.Books.Add(new Book { Title = "C#入門", Price = 2800 });
await db.SaveChangesAsync();
// Read(取得)— SQLではなくLINQで書く
var cheap = await db.Books
.Where(b => b.Price < 3000)
.OrderBy(b => b.Title)
.ToListAsync();
foreach (var b in cheap)
Console.WriteLine($"{b.Id}: {b.Title} ({b.Price}円)");
// Update(更新)— 取得して書き換えて保存するだけ
var target = await db.Books.FirstAsync();
target.Price = 3200;
await db.SaveChangesAsync();
// Delete(削除)
db.Books.Remove(target);
await db.SaveChangesAsync();注目したいのはUpdateです。SQLを書かず、取ってきたオブジェクトのプロパティを変えて SaveChangesAsync() を呼ぶだけ。EF Coreが「何が変わったか」を追跡して、必要なUPDATE文を自動で発行してくれます。
まとめ
EF Core は、SQLを書かずにC#のコードでデータベースを扱える、生産性重視のORMです。
- エンティティクラス+DbContext でモデルを定義する
- マイグレーション(
dotnet ef migrations add→database update)でテーブルを管理する - 取得はLINQ、更新は取得→書き換え→ SaveChangesAsync だけ
手軽な半面、生成されるSQLが見えにくかったり、複雑なクエリでは重くなったりもします。SQLを細かくコントロールしたい場面では Dapper が向きます。どちらを選ぶかは、次の使い分けガイドで整理しています。
👉 あわせて読みたい:C#でデータベースを扱う完全ガイド(ADO.NET・Dapper・EF Core・SqlKataの使い分け)

コメント