0Pricing
C# Academy · レッスン

DbContextとDbSetの基礎

DbContextを設定し、エンティティを定義し、接続文字列を構成して、最初のクエリを実行します。

「DbContextとDbSetの基礎」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。

Entity Framework Coreとは

EF Coreは、.NET公式のオブジェクトリレーショナルマッパー(ORM)です。C#クラス(エンティティ)をデータベースのテーブルにマッピングし、ほとんどの操作でSQLを直接書かずにLINQを使ってデータを検索・保存できます。

エンティティの定義

エンティティとは、プロパティがデータベースの列にマッピングされる単純なC#クラスです。慣例により、Idまたは<TypeName>Idという名前のプロパティが主キーになります。

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public decimal Price { get; set; }
    public int Stock { get; set; }
    public DateTime CreatedAt { get; set; }
}

DbContextの作成

DbContextはデータベースへの入り口です。エンティティごとにDbSet<T>プロパティを保持し、接続、変更追跡、トランザクションを管理します。

using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options) { }

    public DbSet<Product> Products => Set<Product>();
    public DbSet<Order>   Orders   => Set<Order>();
}

DI への DbContext の登録

Program.cs で AddDbContext を呼び出し、コンテキストを Scoped サービスとして登録するとともに、データベースプロバイダーを構成します。

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("Default")));

// For SQLite (great for development/testing):
// options.UseSqlite("Data Source=app.db");

DbSet を使った基本的なクエリ

DbSet<T> は LINQ 演算子を公開します。クエリは列挙されるまで(await ...ToListAsync() が実行されるまで)実行されません。これを遅延実行と呼びます。

public class ProductService
{
    private readonly AppDbContext _db;
    public ProductService(AppDbContext db) => _db = db;

    public async Task<List<Product>> GetExpensiveAsync(decimal minPrice)
    {
        return await _db.Products
            .Where(p => p.Price >= minPrice)
            .OrderBy(p => p.Name)
            .ToListAsync();
    }
}

主キーによる検索

FindAsync はデータベースにアクセスする前に、ローカルの変更追跡キャッシュを確認します。主キーで検索する場合に使用すると、不要な往復通信を避けられます。

var product = await _db.Products.FindAsync(42);
if (product is null)
    throw new KeyNotFoundException("Product not found");

// For complex keys, pass all key values:
var orderLine = await _db.OrderLines.FindAsync(orderId, productId);

新しいレコードの追加

Add を呼び出してエンティティを挿入対象としてキューに追加し、その後 SaveChangesAsync を呼び出して変更を確定します。EF Core が INSERT SQL を生成し、自動生成された Id を設定します。

var product = new Product
{
    Name = "Mechanical Keyboard",
    Price = 149.99m,
    Stock = 50,
    CreatedAt = DateTime.UtcNow
};

_db.Products.Add(product);
await _db.SaveChangesAsync();

Console.WriteLine(product.Id); // Auto-generated PK

レコードの更新

EF Core によって読み込まれたエンティティは追跡されます。プロパティを直接変更して SaveChangesAsync を呼び出すと、EF Core が変更を検出し、最適化された UPDATE 文を生成します。

var product = await _db.Products.FindAsync(42);
if (product is not null)
{
    product.Price = 129.99m;
    product.Stock -= 1;
    await _db.SaveChangesAsync(); // UPDATE Products SET Price=...
}

レコードの削除

Remove を呼び出してエンティティを削除対象としてマークし、その後 SaveChangesAsync を呼び出します。エンティティを読み込まずに一括削除する場合は、.NET 7 以降の ExecuteDeleteAsync を使用します。

// Delete a tracked entity
_db.Products.Remove(product);
await _db.SaveChangesAsync();

// Bulk delete without loading (EF Core 7+)
await _db.Products
    .Where(p => p.Stock == 0)
    .ExecuteDeleteAsync();

Fluent API による構成

OnModelCreating をオーバーライドし、Fluent API を使用してエンティティを構成します。テーブル名、列の型、制約、インデックス、リレーションシップなどを設定できます。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Product>(entity =>
    {
        entity.ToTable("products");
        entity.Property(p => p.Name).IsRequired().HasMaxLength(200);
        entity.Property(p => p.Price).HasColumnType("decimal(18,2)");
        entity.HasIndex(p => p.Name);
    });
}

実践例: DbContext を使ったリポジトリ

一般的なリポジトリでは DbContext をラップし、データアクセスのロジックを集約するとともに、クエリの詳細がサービスクラスに漏れないようにします。

public class ProductRepository : IProductRepository
{
    private readonly AppDbContext _db;
    public ProductRepository(AppDbContext db) => _db = db;

    public async Task<Product?> GetByIdAsync(int id)
        => await _db.Products.AsNoTracking().FirstOrDefaultAsync(p => p.Id == id);

    public async Task<List<Product>> SearchAsync(string query)
        => await _db.Products
            .Where(p => p.Name.Contains(query))
            .AsNoTracking()
            .ToListAsync();
}

理解度チェック

EF Core でクエリを実行するとき、AsNoTracking() は何をしますか?

まとめ: DbContext と DbSet の基本

重要なポイント:

  • DbContext はデータベースとのセッションであり、DbSet<T> はテーブルを表します
  • DI では AddDbContext を使って登録します。デフォルトでは Scoped です
  • LINQ クエリは遅延実行されます。ToListAsync や FirstOrDefaultAsync で実行します
  • 変更追跡により、SaveChangesAsync を使って UPDATE や DELETE を自動的に実行できます
  • 読み取り専用のクエリには AsNoTracking() を使用すると、パフォーマンスを向上できます

よくある質問

「DbContextとDbSetの基礎」レッスンは無料ですか?

はい。「DbContextとDbSetの基礎」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。

「DbContextとDbSetの基礎」で何を学びますか?

DbContextを設定し、エンティティを定義し、接続文字列を構成して、最初のクエリを実行します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「DbContextとDbSetの基礎」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. DbContextとDbSetの基礎
  2. Migrationとスキーマ管理
  3. EF CoreによるCRUD操作
  4. リレーションシップ:一対多と多対多
← C# Academyに戻る