カテゴリ: C# 更新日: 2026/02/21

C#のEF Coreでデータ挿入・更新・削除を完全マスター!初心者でもわかるデータベース操作

C#のEF Coreでデータを挿入・更新・削除する方法
C#のEF Coreでデータを挿入・更新・削除する方法

先生と生徒の会話形式で理解しよう

生徒

「C#でデータベースにデータを保存したり変更したりする方法ってありますか?」

先生

「はい、Entity Framework Core(EF Core)を使えば、データベース操作がとても簡単にできますよ。」

生徒

「データの挿入や更新、削除ってどうやるんですか?」

先生

「それでは、EF Coreを使ったデータベース操作の基本を順番に見ていきましょう!」

1. Entity Framework Core(EF Core)とは?

1. Entity Framework Core(EF Core)とは?
1. Entity Framework Core(EF Core)とは?

Entity Framework Core(エンティティ フレームワーク コア)、通称EF Coreは、C#でデータベースを操作するためのツールです。従来はSQL文(データベース専用の言語)を直接書く必要がありましたが、EF Coreを使うとC#のコードだけでデータベース操作ができます。

例えるなら、EF Coreは「翻訳者」のような存在です。あなたがC#で「このデータを保存して」と指示すると、EF Coreがそれをデータベースが理解できる言葉(SQL)に翻訳して実行してくれます。これにより、プログラミング初心者でもデータベース操作が簡単にできるようになります。

2. EF Coreでデータベース操作を始める準備

2. EF Coreでデータベース操作を始める準備
2. EF Coreでデータベース操作を始める準備

EF Coreを使ってデータベース操作をするには、まず準備が必要です。ここでは、簡単な例として「学生情報」を管理するデータベースを作ってみましょう。

まず、モデルクラスを作成します。モデルクラスとは、データベースのテーブルに対応するC#のクラスのことです。例えば、学生の名前と年齢を保存するテーブルを作る場合、次のようなクラスを定義します。


public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

このクラスは、データベースの「Students」という名前のテーブルに対応します。Idは学生を識別するための番号、Nameは名前、Ageは年齢を表します。

次に、DbContextというクラスを作成します。DbContextは、データベースとの接続を管理し、データの取得や保存を行うための「窓口」のような役割を果たします。


using Microsoft.EntityFrameworkCore;

public class SchoolContext : DbContext
{
    public DbSet<Student> Students { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("接続文字列をここに記述");
    }
}

DbSet<Student>は、Studentテーブルに対する操作を行うためのプロパティです。OnConfiguringメソッドでは、データベースへの接続設定を行います。

3. EF Coreでデータを挿入する方法(Add・SaveChanges)

3. EF Coreでデータを挿入する方法(Add・SaveChanges)
3. EF Coreでデータを挿入する方法(Add・SaveChanges)

データベースに新しいデータを追加することを挿入(Insert)と言います。EF Coreでは、とても簡単にデータを挿入できます。

データを挿入する手順は次の通りです。まず、新しいオブジェクト(インスタンス)を作成し、そのオブジェクトをDbContextに追加して、最後に変更を保存します。


using (var context = new SchoolContext())
{
    // 新しい学生データを作成
    var newStudent = new Student
    {
        Name = "山田太郎",
        Age = 20
    };

    // データベースに追加
    context.Students.Add(newStudent);

    // 変更を保存
    context.SaveChanges();

    Console.WriteLine("データが挿入されました!");
}

このコードでは、まずnew Studentで新しい学生オブジェクトを作成しています。次にcontext.Students.Add(newStudent)でそのオブジェクトをDbContextに追加します。ただし、この時点ではまだデータベースには保存されていません。

最後にcontext.SaveChanges()を呼び出すことで、実際にデータベースにデータが保存されます。SaveChangesは「変更を確定する」という意味です。この呼び出しを忘れると、データは保存されないので注意しましょう。

4. EF Coreでデータを更新する方法(Update・SaveChanges)

4. EF Coreでデータを更新する方法(Update・SaveChanges)
4. EF Coreでデータを更新する方法(Update・SaveChanges)

既にデータベースに保存されているデータを変更することを更新(Update)と言います。EF Coreでは、データを取得して、その内容を変更し、保存するという流れで更新を行います。

例えば、特定の学生の年齢を変更したい場合は、次のようにします。


using (var context = new SchoolContext())
{
    // IDが1の学生を検索
    var student = context.Students.FirstOrDefault(s => s.Id == 1);

    if (student != null)
    {
        // 年齢を更新
        student.Age = 21;

        // 変更を保存
        context.SaveChanges();

        Console.WriteLine("データが更新されました!");
    }
    else
    {
        Console.WriteLine("該当する学生が見つかりませんでした。");
    }
}

このコードでは、まずFirstOrDefaultメソッドを使って、IDが1の学生を検索しています。FirstOrDefaultは、条件に合う最初のデータを取得するメソッドで、見つからない場合はnullを返します。

データが見つかったら、そのプロパティ(ここではAge)を直接変更します。EF Coreは自動的にその変更を追跡しているので、SaveChanges()を呼び出すだけでデータベースに反映されます。

明示的にcontext.Students.Update(student)を呼び出すこともできますが、EF Coreが変更を追跡している場合は不要です。ただし、別のコンテキストから取得したオブジェクトを更新する場合は、Updateメソッドを使う必要があります。

5. EF Coreでデータを削除する方法(Remove・SaveChanges)

5. EF Coreでデータを削除する方法(Remove・SaveChanges)
5. EF Coreでデータを削除する方法(Remove・SaveChanges)

データベースからデータを削除することを削除(Delete)と言います。EF Coreでは、削除したいデータを取得してから、それを削除するという流れになります。

例えば、特定の学生のデータを削除したい場合は、次のようにします。


using (var context = new SchoolContext())
{
    // IDが1の学生を検索
    var student = context.Students.FirstOrDefault(s => s.Id == 1);

    if (student != null)
    {
        // データを削除
        context.Students.Remove(student);

        // 変更を保存
        context.SaveChanges();

        Console.WriteLine("データが削除されました!");
    }
    else
    {
        Console.WriteLine("該当する学生が見つかりませんでした。");
    }
}

このコードでは、context.Students.Remove(student)でデータを削除対象としてマークします。そしてSaveChanges()を呼び出すことで、実際にデータベースからデータが削除されます。

複数のデータを一度に削除したい場合は、RemoveRangeメソッドを使います。例えば、年齢が18歳未満の学生を全員削除する場合は次のようにします。


using (var context = new SchoolContext())
{
    // 年齢が18歳未満の学生を全て取得
    var youngStudents = context.Students.Where(s => s.Age < 18).ToList();

    // 複数のデータを削除
    context.Students.RemoveRange(youngStudents);

    // 変更を保存
    context.SaveChanges();

    Console.WriteLine($"{youngStudents.Count}件のデータが削除されました!");
}

6. SaveChangesの重要性とトランザクション

6. SaveChangesの重要性とトランザクション
6. SaveChangesの重要性とトランザクション

SaveChanges()メソッドは、EF Coreでのデータベース操作において非常に重要な役割を果たします。このメソッドを呼び出すまで、Add、Update、Removeなどの操作はメモリ上で追跡されているだけで、実際のデータベースには反映されていません。

SaveChanges()を呼び出すと、EF Coreは追跡していた全ての変更を一つのトランザクションとしてデータベースに送信します。トランザクションとは、複数の操作を「一つのまとまり」として扱う仕組みです。

例えば、銀行の送金を考えてみましょう。AさんからBさんに1万円を送金する場合、「Aさんの口座から1万円を引く」と「Bさんの口座に1万円を足す」という2つの操作が必要です。もし最初の操作だけ成功して2つ目が失敗したら、お金が消えてしまいます。トランザクションを使うと、両方の操作が成功した場合のみ変更が確定され、どちらかが失敗した場合は全てキャンセルされます。

EF Coreでは、SaveChanges()が失敗した場合、その前に行った全ての変更が自動的にロールバック(取り消し)されます。これにより、データベースの整合性が保たれます。

7. 非同期処理でデータベース操作を行う方法

7. 非同期処理でデータベース操作を行う方法
7. 非同期処理でデータベース操作を行う方法

データベース操作は時間がかかることがあります。特に大量のデータを扱う場合や、ネットワーク経由でデータベースにアクセスする場合は、処理が完了するまで待つ必要があります。

この待ち時間の間、プログラムが完全に停止してしまうと、ユーザーインターフェースが固まったり、他の処理ができなくなったりします。これを解決するのが非同期処理です。

EF Coreは、全ての主要なメソッドに非同期版を用意しています。非同期版のメソッドには「Async」という名前が付いています。例えば、SaveChanges()の非同期版はSaveChangesAsync()です。


public async Task InsertStudentAsync()
{
    using (var context = new SchoolContext())
    {
        var newStudent = new Student
        {
            Name = "佐藤花子",
            Age = 19
        };

        context.Students.Add(newStudent);

        // 非同期で保存
        await context.SaveChangesAsync();

        Console.WriteLine("データが非同期で挿入されました!");
    }
}

非同期処理を使う場合は、メソッドにasyncキーワードを付け、非同期メソッドの呼び出しにはawaitキーワードを付けます。これにより、データベース処理の完了を待っている間も、他の処理を実行できるようになります。

現代のアプリケーション開発では、非同期処理が推奨されています。特にWebアプリケーションやモバイルアプリケーションでは、ユーザー体験を向上させるために非常に重要です。

8. エラーハンドリングとデバッグのコツ

8. エラーハンドリングとデバッグのコツ
8. エラーハンドリングとデバッグのコツ

データベース操作では、様々なエラーが発生する可能性があります。例えば、ネットワーク接続の問題、データベースの容量不足、データの制約違反などです。これらのエラーに適切に対処することが重要です。

try-catch文を使うと、エラーが発生した場合でもプログラムがクラッシュせずに、適切な処理を行うことができます。try-catch文は、「試してみて、失敗したらこうする」という仕組みです。


using (var context = new SchoolContext())
{
    try
    {
        var newStudent = new Student
        {
            Name = "鈴木一郎",
            Age = 22
        };

        context.Students.Add(newStudent);
        context.SaveChanges();

        Console.WriteLine("データが正常に挿入されました。");
    }
    catch (DbUpdateException ex)
    {
        Console.WriteLine("データベースの更新中にエラーが発生しました。");
        Console.WriteLine($"エラー内容: {ex.Message}");
    }
    catch (Exception ex)
    {
        Console.WriteLine("予期しないエラーが発生しました。");
        Console.WriteLine($"エラー内容: {ex.Message}");
    }
}

このコードでは、tryブロックの中でデータベース操作を行っています。もしエラーが発生した場合、catchブロックが実行されます。DbUpdateExceptionは、データベース更新時に発生する特定のエラーをキャッチします。その他の予期しないエラーは、一般的なExceptionでキャッチします。

デバッグの際には、Visual Studioのブレークポイント機能を使うと便利です。コードの任意の行にブレークポイントを設定すると、その行でプログラムの実行が一時停止し、変数の値を確認できます。また、EF Coreが実行するSQL文をログに出力することもでき、これにより何が起こっているのかを詳しく確認できます。

9. 実践的な例:学生管理システムの完成形

9. 実践的な例:学生管理システムの完成形
9. 実践的な例:学生管理システムの完成形

ここまで学んだ挿入、更新、削除の操作を組み合わせて、簡単な学生管理システムを作ってみましょう。このシステムでは、メニューを表示して、ユーザーが選んだ操作を実行します。


using System;
using System.Linq;

class Program
{
    static void Main()
    {
        while (true)
        {
            Console.WriteLine("\n=== 学生管理システム ===");
            Console.WriteLine("1. 学生を追加");
            Console.WriteLine("2. 学生情報を更新");
            Console.WriteLine("3. 学生を削除");
            Console.WriteLine("4. 全学生を表示");
            Console.WriteLine("5. 終了");
            Console.Write("選択してください: ");

            var choice = Console.ReadLine();

            using (var context = new SchoolContext())
            {
                switch (choice)
                {
                    case "1":
                        Console.Write("名前: ");
                        var name = Console.ReadLine();
                        Console.Write("年齢: ");
                        var age = int.Parse(Console.ReadLine());

                        var newStudent = new Student { Name = name, Age = age };
                        context.Students.Add(newStudent);
                        context.SaveChanges();
                        Console.WriteLine("学生が追加されました。");
                        break;

                    case "2":
                        Console.Write("更新する学生のID: ");
                        var updateId = int.Parse(Console.ReadLine());
                        var studentToUpdate = context.Students.FirstOrDefault(s => s.Id == updateId);

                        if (studentToUpdate != null)
                        {
                            Console.Write("新しい年齢: ");
                            studentToUpdate.Age = int.Parse(Console.ReadLine());
                            context.SaveChanges();
                            Console.WriteLine("学生情報が更新されました。");
                        }
                        else
                        {
                            Console.WriteLine("学生が見つかりませんでした。");
                        }
                        break;

                    case "3":
                        Console.Write("削除する学生のID: ");
                        var deleteId = int.Parse(Console.ReadLine());
                        var studentToDelete = context.Students.FirstOrDefault(s => s.Id == deleteId);

                        if (studentToDelete != null)
                        {
                            context.Students.Remove(studentToDelete);
                            context.SaveChanges();
                            Console.WriteLine("学生が削除されました。");
                        }
                        else
                        {
                            Console.WriteLine("学生が見つかりませんでした。");
                        }
                        break;

                    case "4":
                        var allStudents = context.Students.ToList();
                        Console.WriteLine("\n--- 全学生一覧 ---");
                        foreach (var student in allStudents)
                        {
                            Console.WriteLine($"ID: {student.Id}, 名前: {student.Name}, 年齢: {student.Age}");
                        }
                        break;

                    case "5":
                        Console.WriteLine("終了します。");
                        return;

                    default:
                        Console.WriteLine("無効な選択です。");
                        break;
                }
            }
        }
    }
}

このプログラムは、メニュー駆動型のシステムです。ユーザーが番号を入力すると、対応する操作が実行されます。while (true)により、ユーザーが「5」を選んで終了するまで、メニューが繰り返し表示されます。

各操作でusing (var context = new SchoolContext())を使用していますが、これは処理が終わったら自動的にデータベース接続を閉じるためです。usingステートメントを使うと、リソースの管理が自動的に行われ、メモリリークを防ぐことができます。

10. パフォーマンスを向上させるテクニック

10. パフォーマンスを向上させるテクニック
10. パフォーマンスを向上させるテクニック

EF Coreを使う際、パフォーマンスを意識することも重要です。特に大量のデータを扱う場合、適切な方法を使わないと処理が非常に遅くなることがあります。

変更追跡を無効にする:データを読み取るだけで更新しない場合、変更追跡を無効にすることでパフォーマンスが向上します。AsNoTracking()メソッドを使います。


using (var context = new SchoolContext())
{
    // 読み取り専用のクエリ
    var students = context.Students
        .AsNoTracking()
        .Where(s => s.Age >= 20)
        .ToList();

    foreach (var student in students)
    {
        Console.WriteLine($"{student.Name} - {student.Age}歳");
    }
}

一括操作を活用する:複数のデータを挿入する場合、一つずつAddを呼び出すより、AddRangeを使った方が効率的です。

必要なデータだけを取得する:全てのプロパティが必要ない場合は、Selectメソッドを使って必要なデータだけを取得しましょう。これにより、ネットワーク通信量が減り、処理速度が向上します。

適切なインデックスを設定する:データベース側で検索によく使うカラムにインデックスを設定すると、検索速度が大幅に向上します。EF Coreでは、Fluent APIを使ってインデックスを設定できます。

これらのテクニックを組み合わせることで、より高速で効率的なアプリケーションを作ることができます。ただし、最初から完璧を目指す必要はありません。まずは基本的な操作を理解し、必要に応じて最適化していくのが良いでしょう。

カテゴリの一覧へ
新着記事
New1
COBOL
COBOLプログラムの軽量化!デバッグ文と不要コードの削除で効率アップ
New2
C#
C#のインストール方法まとめ!Windows・Mac・Linux別にステップ解説
New3
COBOL
COBOLモダナイゼーションのコスト見積もりとROI(投資対効果)を徹底解説!
New4
C#
C#の文字列の長さを取得する方法!Lengthプロパティを初心者向けに解説
人気記事
No.1
Java&Spring記事人気No1
C#
C#のpartialクラスとは?初心者でも理解できるクラス分割の基本
No.2
Java&Spring記事人気No2
C#
C#のLINQでOrderByを使った並び替えを完全ガイド!初心者でもわかるソート方法
No.3
Java&Spring記事人気No3
C#
C#のデータベース接続文字列の設定方法を完全ガイド!ADO.NETとEntity Framework初心者向け
No.4
Java&Spring記事人気No4
COBOL
COBOLのCOPY句の使い方を完全ガイド!初心者でもわかる共通部品の再利用方法
No.5
Java&Spring記事人気No5
C#
C#のLINQでFirstとFirstOrDefaultの違いと使い方を完全解説!初心者向けガイド
No.6
Java&Spring記事人気No6
C#
C# Entity Frameworkとは?初心者でもわかる基本概念とデータベース操作
No.7
Java&Spring記事人気No7
COBOL
COBOLの数値データ型「PIC 9」の使い方と注意点をやさしく解説!
No.8
Java&Spring記事人気No8
C#
C#のトランザクション処理を完全ガイド!初心者でもわかるCommit・Rollbackの使い方