EF CoreによるCRUD操作
EF Coreの変更追跡とSaveChangesを使って、Create、Read、Update、Delete操作を実行します。
「EF CoreによるCRUD操作」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。
EF Core の CRUD 概要
EF Core は、変更追跡と SaveChangesAsync() を組み合わせて、4 つの CRUD 操作(作成、読み取り、更新、削除)すべてを処理します。変更追跡の仕組みを理解することが、CRUD を使いこなす鍵です。
作成: 新しいエンティティの追加
DbSet.Add() または AddAsync() を使用して、エンティティを Added としてマークします。SaveChangesAsync() を呼び出すと、EF Core が INSERT を生成し、自動インクリメントキーを設定します。
var order = new Order
{
CustomerId = 5,
PlacedAt = DateTime.UtcNow,
Status = OrderStatus.Pending
};
await _db.Orders.AddAsync(order);
await _db.SaveChangesAsync();
Console.WriteLine(order.Id); // populated by DBエンティティグラフの追加
1 回の呼び出しで親と子を追加すると、オブジェクトグラフ全体が挿入されます。EF Core が FK リレーションシップを自動的に解決します。
var order = new Order
{
CustomerId = 5,
PlacedAt = DateTime.UtcNow,
Lines = new List<OrderLine>
{
new() { ProductId = 10, Quantity = 2, Price = 49.99m },
new() { ProductId = 11, Quantity = 1, Price = 19.99m }
}
};
_db.Orders.Add(order);
await _db.SaveChangesAsync();
// Inserts Order + 2 OrderLines in one transaction読み取り: LINQ によるクエリ
EF Core は LINQ 式を SQL に変換します。Where、Select、OrderBy などを使ってクエリを組み立て、ToListAsync または FirstOrDefaultAsync で具体化します。
// Read all pending orders for a customer
var orders = await _db.Orders
.Where(o => o.CustomerId == 5 && o.Status == OrderStatus.Pending)
.OrderByDescending(o => o.PlacedAt)
.Select(o => new OrderSummaryDto
{
Id = o.Id,
Total = o.Lines.Sum(l => l.Quantity * l.Price),
Status = o.Status.ToString()
})
.ToListAsync();読み取り: 単一エンティティの検索
単一エンティティを読み取る場合は、FindAsync(最初に変更追跡を確認)を使用するか、述語を指定した FirstOrDefaultAsync または SingleOrDefaultAsync を使用します。
// By PK (checks cache first)
var order = await _db.Orders.FindAsync(orderId);
// By predicate (always hits DB)
var latest = await _db.Orders
.Where(o => o.CustomerId == 5)
.OrderByDescending(o => o.PlacedAt)
.FirstOrDefaultAsync();更新: 変更追跡
EF Core 経由で読み込まれたエンティティは追跡されます。プロパティを直接変更して SaveChangesAsync() を呼び出します。EF Core が差分を検出し、最小限の UPDATE 文を生成します。
var order = await _db.Orders.FindAsync(orderId);
if (order is null) return;
order.Status = OrderStatus.Shipped;
order.ShippedAt = DateTime.UtcNow;
await _db.SaveChangesAsync();
// UPDATE Orders SET Status=..., ShippedAt=... WHERE Id=orderId更新: 一括更新(EF Core 7 以降)
ExecuteUpdateAsync はエンティティを読み込まず、データベース内の行を直接更新します。一括操作では、はるかに効率的です。
// Mark all overdue orders as Cancelled — no loading needed
await _db.Orders
.Where(o => o.Status == OrderStatus.Pending
&& o.PlacedAt < DateTime.UtcNow.AddDays(-30))
.ExecuteUpdateAsync(set => set
.SetProperty(o => o.Status, OrderStatus.Cancelled)
.SetProperty(o => o.UpdatedAt, DateTime.UtcNow));削除: 単一エンティティの削除
追跡中のエンティティに対して Remove() を呼び出し、その後 SaveChangesAsync() を呼び出します。ID しかない場合は、先に検索するか、ExecuteDeleteAsync を使用します。
var order = await _db.Orders.FindAsync(orderId);
if (order is null) return;
_db.Orders.Remove(order);
await _db.SaveChangesAsync();
// DELETE FROM Orders WHERE Id=orderId削除: 一括削除(EF Core 7 以降)
ExecuteDeleteAsync はエンティティを読み込まずに、単一の DELETE SQL 文を発行します。バッチクリーンアップ操作に最適です。
// Delete all cancelled orders older than 1 year
int deleted = await _db.Orders
.Where(o => o.Status == OrderStatus.Cancelled
&& o.PlacedAt < DateTime.UtcNow.AddYears(-1))
.ExecuteDeleteAsync();
Console.WriteLine($"Deleted {deleted} old orders");トランザクション
1 回の SaveChangesAsync 呼び出し内のすべての操作は、トランザクションにまとめられます。複数回の保存にまたがる複数ステップの操作では、明示的なトランザクションを使用します。
using var transaction = await _db.Database.BeginTransactionAsync();
try
{
_db.Orders.Add(newOrder);
await _db.SaveChangesAsync();
inventory.Stock -= newOrder.Quantity;
await _db.SaveChangesAsync();
await transaction.CommitAsync();
}
catch
{
await transaction.RollbackAsync();
throw;
}実践例: 完全な CRUD サービス
完全なサービスでは、適切なエラー処理ですべての CRUD 操作をラップし、エンティティの内部構造を公開しないよう DTO を返します。
public async Task<OrderDto> CreateOrderAsync(CreateOrderRequest req)
{
var order = new Order { CustomerId = req.CustomerId, PlacedAt = DateTime.UtcNow };
_db.Orders.Add(order);
await _db.SaveChangesAsync();
return new OrderDto { Id = order.Id, Status = order.Status.ToString() };
}
public async Task<bool> CancelOrderAsync(int id)
{
int rows = await _db.Orders
.Where(o => o.Id == id && o.Status == OrderStatus.Pending)
.ExecuteUpdateAsync(s =>
s.SetProperty(o => o.Status, OrderStatus.Cancelled));
return rows > 0;
}理解度チェック
エンティティを読み込んで SaveChangesAsync を呼び出す方法と比べて、ExecuteUpdateAsync / ExecuteDeleteAsync にはどのような利点がありますか?
まとめ: EF Core の CRUD 操作
重要なポイント:
- Add + SaveChangesAsync → INSERT。EF Core が自動生成キーを設定します
- 追跡中のエンティティを変更 + SaveChangesAsync → 最小限の UPDATE
- Remove + SaveChangesAsync → 単一エンティティの DELETE
- ExecuteUpdateAsync / ExecuteDeleteAsync → エンティティを読み込まない一括操作(EF Core 7 以降)
- 複数ステップの操作は、原子性を確保するため明示的なトランザクションにまとめます
よくある質問
「EF CoreによるCRUD操作」レッスンは無料ですか?
はい。「EF CoreによるCRUD操作」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。
「EF CoreによるCRUD操作」で何を学びますか?
EF Coreの変更追跡とSaveChangesを使って、Create、Read、Update、Delete操作を実行します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C# Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「EF CoreによるCRUD操作」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC# Academyレッスンでコードを書いて実行できますか?
はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- DbContextとDbSetの基礎
- Migrationとスキーマ管理
- EF CoreによるCRUD操作
- リレーションシップ:一対多と多対多