C# EF CoreのDbContextの使い方完全ガイド!初心者でもわかるデータベース操作
生徒
「C#でデータベースを操作するには、どうすればいいんですか?」
先生
「C#では、Entity Framework Core(EF Core)というツールを使って、簡単にデータベースを操作できます。その中心となるのがDbContextというクラスです。」
生徒
「DbContextって何ですか?難しそうですね…」
先生
「心配いりません。DbContextは、データベースとC#プログラムをつなぐ橋のようなものです。これを使えば、SQLを書かなくてもデータベース操作ができるんですよ。」
生徒
「それは便利ですね!具体的にどうやって使うんですか?」
先生
「それでは、基本的な使い方から順番に見ていきましょう!」
1. Entity Framework Core(EF Core)とは?
Entity Framework Core(エンティティフレームワークコア)は、マイクロソフトが提供するデータベース操作のためのツールです。通常、データベースを操作するにはSQL(エスキューエル)という専用の言語を書く必要がありますが、EF Coreを使えば、C#のコードだけでデータベースを操作できます。
例えるなら、EF Coreは「翻訳機」のようなものです。あなたが日本語で話すと、それを自動的に英語に翻訳してくれる翻訳機があるように、EF CoreはC#のコードをSQLに自動変換してくれます。これにより、プログラミング初心者でもデータベース操作が簡単にできるようになります。
ADO.NET(エーディーオードットネット)という従来の方法もありますが、EF Coreの方がより直感的で、コード量も少なくて済むため、現代のC#開発では広く使われています。
2. DbContextとは何か?
DbContext(ディービーコンテキスト)は、EF Coreの中心となるクラスです。このクラスは、データベースとの接続を管理し、データの追加、取得、更新、削除といった操作を行うための窓口になります。
身近な例で説明すると、DbContextは「図書館の司書さん」のようなものです。あなたが本を借りたいとき、司書さんに「この本を貸してください」とお願いすれば、司書さんが本棚から本を探して持ってきてくれます。同じように、DbContextに「このデータを取得してください」とお願いすれば、データベースからデータを持ってきてくれるのです。
DbContextには以下のような役割があります:
- データベースへの接続を管理する
- データの取得、追加、更新、削除を行う
- 変更をデータベースに保存する
- テーブルとC#のクラスを結びつける
3. DbContextの基本的な作り方
DbContextを使うには、まず自分専用のDbContextクラスを作る必要があります。これは、Entity FrameworkのDbContextクラスを継承(けいしょう)して作ります。継承とは、既にあるクラスの機能を引き継いで、新しいクラスを作ることです。
例えば、商品を管理するデータベースを作る場合、まず商品を表すクラスとDbContextクラスを以下のように作成します。
using Microsoft.EntityFrameworkCore;
// 商品を表すクラス(モデル)
public class Product
{
public int Id { get; set; } // 商品ID
public string Name { get; set; } // 商品名
public int Price { get; set; } // 価格
}
// DbContextクラスの作成
public class ShopDbContext : DbContext
{
// 商品テーブルを表すDbSet
public DbSet<Product> Products { get; set; }
// データベース接続の設定
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=shop.db");
}
}
このコードでは、Productクラスがデータベースのテーブルの1行を表します。ShopDbContextクラスがDbContextを継承していて、DbSet<Product>という部分で商品テーブルを定義しています。DbSet(ディービーセット)は、テーブル全体を表すコレクションのようなものです。
OnConfiguringメソッドでは、どのデータベースに接続するかを設定しています。ここではSQLite(エスキューライト)という軽量データベースを使っています。
4. データの追加(INSERT操作)
DbContextを使ってデータベースに新しいデータを追加する方法を見ていきましょう。データの追加は、以下の手順で行います。
- DbContextのインスタンスを作成する
- 新しいデータ(オブジェクト)を作る
- DbSetに追加する
- SaveChangesメソッドで保存する
using (var context = new ShopDbContext())
{
// 新しい商品を作成
var newProduct = new Product
{
Name = "ノートパソコン",
Price = 89800
};
// DbSetに追加
context.Products.Add(newProduct);
// データベースに保存
context.SaveChanges();
Console.WriteLine("商品を追加しました!");
}
この例では、using文を使ってDbContextを作成しています。using文を使うと、処理が終わった後に自動的にデータベース接続を閉じてくれるので便利です。
Addメソッドで新しい商品をDbSetに追加し、SaveChangesメソッドを呼ぶことで、実際にデータベースに保存されます。SaveChangesを呼ばないと、データベースには保存されないので注意が必要です。これは、ワープロソフトで文章を書いた後に「保存」ボタンを押すのと同じです。
商品を追加しました!
5. データの取得(SELECT操作)
データベースからデータを取得する方法を学びましょう。EF Coreでは、LINQ(リンク)という機能を使ってデータを検索できます。LINQは、C#でコレクションやデータベースを簡単に操作するための仕組みです。
データ取得の基本的な方法をいくつか紹介します。
using (var context = new ShopDbContext())
{
// すべての商品を取得
var allProducts = context.Products.ToList();
Console.WriteLine("=== すべての商品 ===");
foreach (var product in allProducts)
{
Console.WriteLine($"ID: {product.Id}, 名前: {product.Name}, 価格: {product.Price}円");
}
// 条件で絞り込み(価格が5万円以上の商品)
var expensiveProducts = context.Products
.Where(p => p.Price >= 50000)
.ToList();
Console.WriteLine("\n=== 5万円以上の商品 ===");
foreach (var product in expensiveProducts)
{
Console.WriteLine($"{product.Name}: {product.Price}円");
}
// 1つだけ取得(IDが1の商品)
var firstProduct = context.Products.FirstOrDefault(p => p.Id == 1);
if (firstProduct != null)
{
Console.WriteLine($"\n最初の商品: {firstProduct.Name}");
}
}
ToListメソッドは、データベースから実際にデータを取得してリストに変換します。Whereメソッドは条件でデータを絞り込みます。FirstOrDefaultは最初の1件を取得しますが、見つからない場合はnullを返します。
LINQを使うと、SQLを書かなくても、C#のコードだけで複雑な検索ができるのが大きなメリットです。
=== すべての商品 ===
ID: 1, 名前: ノートパソコン, 価格: 89800円
ID: 2, 名前: マウス, 価格: 1980円
=== 5万円以上の商品 ===
ノートパソコン: 89800円
最初の商品: ノートパソコン
6. データの更新(UPDATE操作)
既存のデータを更新する方法を説明します。データ更新は、まずデータを取得し、そのプロパティを変更してから、SaveChangesを呼ぶという流れになります。
using (var context = new ShopDbContext())
{
// 更新したい商品を取得
var product = context.Products.FirstOrDefault(p => p.Id == 1);
if (product != null)
{
Console.WriteLine($"変更前: {product.Name} - {product.Price}円");
// 価格を変更
product.Price = 79800;
product.Name = "ノートパソコン(値下げ)";
// データベースに保存
context.SaveChanges();
Console.WriteLine($"変更後: {product.Name} - {product.Price}円");
Console.WriteLine("商品情報を更新しました!");
}
}
EF Coreは変更追跡(へんこうついせき)という機能を持っています。DbContextから取得したオブジェクトのプロパティを変更すると、EF Coreが自動的にその変更を記録します。そして、SaveChangesを呼ぶと、変更された部分だけをデータベースに反映してくれます。
これは、ワープロソフトで文書を編集しているときに、変更した箇所を自動的に記録してくれる機能に似ています。
変更前: ノートパソコン - 89800円
変更後: ノートパソコン(値下げ) - 79800円
商品情報を更新しました!
7. データの削除(DELETE操作)
データベースからデータを削除する方法を見ていきましょう。削除も更新と同じように、まずデータを取得してから削除します。
using (var context = new ShopDbContext())
{
// 削除したい商品を取得
var product = context.Products.FirstOrDefault(p => p.Id == 2);
if (product != null)
{
Console.WriteLine($"削除する商品: {product.Name}");
// 商品を削除
context.Products.Remove(product);
// データベースに反映
context.SaveChanges();
Console.WriteLine("商品を削除しました!");
}
else
{
Console.WriteLine("指定された商品が見つかりませんでした。");
}
}
RemoveメソッドでDbSetからオブジェクトを削除します。そして、SaveChangesを呼ぶことで、実際にデータベースからも削除されます。削除する前に、本当に削除していいかを確認する処理を入れると、誤って削除してしまうことを防げます。
削除する商品: マウス
商品を削除しました!
8. SaveChangesメソッドの重要性
ここまで何度も登場しているSaveChangesメソッドについて、もう少し詳しく説明します。
DbContextで行った追加、更新、削除の操作は、SaveChangesを呼ぶまではメモリ上にしか存在しません。つまり、実際のデータベースには反映されていない状態です。SaveChangesを呼ぶことで初めて、これらの変更がデータベースに書き込まれます。
これは銀行のATMで振込をするときに似ています。金額や振込先を入力しても、最後に「確認」ボタンを押さないと実際には振り込まれませんよね。SaveChangesは、その「確認」ボタンのような役割を果たします。
- Add、Update、Removeだけではデータベースは変更されない
- SaveChangesを呼んで初めてデータベースに反映される
- 複数の変更をまとめて1回のSaveChangesで保存できる
- SaveChangesが成功すると、変更されたレコード数が返される
9. DbContextのライフサイクルとusing文
DbContextはデータベース接続というリソースを使います。リソースとは、コンピュータの限られた資源のことで、使い終わったら必ず解放(返却)する必要があります。
これまでの例で使ってきたusing文は、この解放処理を自動的に行ってくれる便利な仕組みです。using文のブロックを抜けると、自動的にDbContextが破棄され、データベース接続も閉じられます。
レンタカーを借りることを想像してください。車を借りたら、使い終わったら必ず返却しないといけませんよね。using文は、この返却手続きを自動的にやってくれる仕組みなのです。
DbContextは長時間保持せず、必要なときに作成して、使い終わったらすぐに破棄するのが基本です。ASP.NETなどのWebアプリケーションでは、1つのHTTPリクエストごとにDbContextを作成し、レスポンス送信後に破棄するのが一般的なパターンです。
10. エラーハンドリングとトランザクション
実際のアプリケーション開発では、データベース操作でエラーが発生する可能性を考慮する必要があります。ネットワークの問題、データの制約違反など、様々な原因でエラーが起こりえます。