C# ORMおすすめ比較|Entity Framework CoreとDapperの違い・選び方を初心者向けに解説
はじめに
C#でWebアプリケーションや業務システムを開発していると、ほぼ必ずデータベース操作が必要になります。そこでよく出てくるのが「C# ORM」というキーワードです。
ORMを使うと、SQLを毎回細かく書かなくても、C#のクラスやオブジェクトを通じてデータベースを操作できます。特にASP.NET Coreでアプリケーションを作る場合、Entity Framework Core、通称EF Coreは定番の選択肢です。一方で、より高速でSQLを細かく制御したい場合はDapperがよく使われます。
ただし、初心者にとっては「EF CoreとDapperは何が違うのか」「結局どちらを選べばよいのか」が分かりづらいポイントです。この記事では、C# ORMの基礎から、Entity Framework CoreとDapperの違い、目的別の選び方、簡単な実装イメージまで初心者向けに解説します。
1. C#のORMとは?まず押さえるべき基礎知識
1-1. ORMとは何か:データベース操作をC#のオブジェクトで扱う仕組み
ORMとは「Object-Relational Mapping」の略で、日本語では「オブジェクト関係マッピング」と呼ばれます。簡単に言うと、データベースのテーブルとC#のクラスを対応付け、レコードをC#のオブジェクトとして扱えるようにする仕組みです。
たとえば、データベースに次のようなUsersテーブルがあるとします。
SQLUsers
- Id
- Name
ORMを使う場合、C#側では次のようなクラスとして表現できます。
C#public class User
{
public int Id { get; set; }
public string Name { get; set; } = "";
public string Email { get; set; } = "";
}
このように、テーブルの行をUserオブジェクトとして扱えるため、C#らしい書き方でデータ取得・登録・更新・削除ができます。EF Coreは、.NET開発者が.NETオブジェクトを使ってデータベースを扱えるO/RMとして公式に説明されています。
1-2. ADO.NET・SQL直書き・ORMの違い
C#でデータベースを操作する方法は、大きく分けると次の3つがあります。
| 方法 | 特徴 | 向いているケース |
|---|---|---|
| ADO.NET | 接続、コマンド、DataReaderなどを直接扱う | 細かく制御したい処理 |
| SQL直書き | SQLを自分で書いて実行する | 複雑な検索・集計 |
| ORM | C#のオブジェクト経由でDB操作する | CRUD中心のアプリ開発 |
ADO.NETは低レベルなデータアクセスの仕組みで、自由度は高いものの、接続管理や値の取り出しなどのコードが多くなりがちです。
SQL直書きは、実行されるSQLを開発者が完全に把握しやすい反面、SQL文字列の管理や結果のマッピングを自分で行う必要があります。
ORMは、こうした手間を減らし、C#のコードからデータベースを扱いやすくするための仕組みです。特にEF Coreのようなフル機能ORMでは、LINQによるクエリ、変更追跡、マイグレーションなどが利用できます。EF CoreはLINQを使って強く型付けされたクエリを書き、データベースプロバイダーがSQLなどのデータベース固有言語に変換する仕組みです。
1-3. C#開発でORMを使うメリットと注意点
C#開発でORMを使う主なメリットは、開発効率と保守性の向上です。
まず、データベースのテーブルをC#のクラスとして扱えるため、コードの見通しがよくなります。SQLを大量に書かなくても、context.Users.ToListAsync()のような形でデータを取得できます。
また、EF Coreであればマイグレーション機能を使って、C#のモデル変更に合わせてデータベーススキーマを段階的に更新できます。EF Coreのマイグレーションは、アプリケーションのデータモデルとデータベーススキーマを同期させるための仕組みとして提供されています。
一方で、ORMには注意点もあります。ORMが生成するSQLを理解せずに使うと、想定外に重いクエリが実行されることがあります。また、複雑な集計や大量データ処理では、ORM任せにするよりもSQLを直接書いたほうが分かりやすく、高速な場合もあります。
つまり、ORMはSQLを完全に不要にする道具ではありません。SQLの基礎を理解したうえで、C#のコードを効率よく書くために使うものです。
1-4. ORMが向いているプロジェクト・向いていないプロジェクト
ORMが向いているのは、ユーザー管理、商品管理、受注管理、問い合わせ管理など、CRUD処理が中心のアプリケーションです。CRUDとは、Create、Read、Update、Deleteの略で、登録・取得・更新・削除を意味します。
たとえば、次のようなプロジェクトではORMが効果的です。
ASP.NET CoreのWebアプリ
管理画面付きの業務システム
社内向けCRUDアプリ
中小規模のWebサービス
ドメインモデルを重視するアプリケーション
一方で、ORMがあまり向いていないケースもあります。
大量データを高速に処理するバッチ
複雑なSQLチューニングが必要な検索処理
ストアドプロシージャ中心の既存システム
SQLの実行内容を完全に制御したいプロジェクト
データベース構造が非常に特殊なシステム
このような場合は、DapperやADO.NET、SQL直書きのほうが適していることがあります。
2. C#で使える主なORM・データアクセスライブラリ一覧
2-1. Entity Framework Core
Entity Framework Coreは、Microsoftが提供するC#向けの代表的なORMです。軽量、拡張可能、オープンソース、クロスプラットフォームなデータアクセス技術として位置付けられています。
EF Coreの特徴は、LINQでクエリを書けること、変更追跡により更新処理を書きやすいこと、マイグレーションでスキーマ管理ができることです。ASP.NET Coreとの相性もよく、初心者が最初に学ぶC# ORMとして有力な選択肢です。
2-2. Dapper
Dapperは、シンプルで高速なMicro ORMです。ADO.NETのDbConnectionに拡張メソッドを追加し、SQL実行とオブジェクトへのマッピングを簡単にしてくれます。公式READMEでも、DapperはDbConnectionを拡張し、同期・非同期のデータアクセスやバッファあり・なしのクエリに対応すると説明されています。
DapperはSQLを自分で書くスタイルなので、EF CoreのようにSQLを大きく隠蔽するものではありません。SQLを細かく制御したい場合や、パフォーマンスを重視する場合に向いています。
2-3. NHibernate
NHibernateは、.NET向けの成熟したオープンソースORMです。公式サイトでも、成熟したフル機能のORMとして説明されています。
歴史が長く、高度なマッピングや複雑なドメインモデルに対応できる一方で、EF Coreに比べると初心者向けの情報やASP.NET Coreでの採用例はやや少なめです。既存プロジェクトで使われている場合や、細かなORM機能が必要な場合に検討するとよいでしょう。
2-4. LINQ to DB
LINQ to DBは、LINQを使ってデータベースにアクセスできる軽量なデータアクセスライブラリです。公式READMEでは、POCOとデータベースの間にシンプルで軽量、高速、型安全なレイヤーを提供するライブラリとして説明されています。
EF Coreほど多機能ではありませんが、LINQでクエリを書きたい、かつ軽量な仕組みを使いたい場合に選択肢になります。
2-5. RepoDB
RepoDBは、フルORMとMicro ORMの中間を狙ったデータアクセスライブラリです。DapperよりもCRUD支援があり、EF Coreよりも軽量に扱えることを目指したライブラリです。
SQLをある程度制御しながら、単純なCRUDの実装量を減らしたい場合に候補になります。ただし、情報量や利用者数を重視するなら、まずはEF CoreとDapperを比較したほうが判断しやすいです。
2-6. 初心者が最初に比較すべきORMはEF CoreとDapper
C# ORMを初めて選ぶなら、まず比較すべきなのはEntity Framework CoreとDapperです。
EF Coreは、C#のオブジェクト中心で開発したい場合に向いています。SQLをあまり書かずにCRUD処理を実装でき、マイグレーションや変更追跡などの便利な機能もあります。
Dapperは、SQLを自分で書きたい場合に向いています。ORMとしての機能は最小限ですが、その分軽量で高速です。
初心者がC# ORMを学ぶ場合は、まずEF CoreでORMの考え方を理解し、その後DapperでSQL制御やパフォーマンス重視の実装を学ぶ流れがおすすめです。
3. Entity Framework Coreとは?特徴・メリット・デメリット
3-1. EF Coreの基本機能:LINQ・変更追跡・マイグレーション
EF Coreの代表的な機能は、LINQ、変更追跡、マイグレーションです。
LINQを使うと、SQLではなくC#の構文でクエリを書けます。
C#var users = await context.Users
.Where(u => u.Name.Contains("佐藤"))
.ToListAsync();
このコードは、Usersテーブルから名前に「佐藤」を含むユーザーを取得する処理です。EF CoreはこのLINQクエリをデータベース向けのSQLに変換して実行します。
変更追跡は、取得したエンティティの変更状態をEF Coreが管理する機能です。たとえば、取得したユーザーの名前を変更してSaveChangesAsync()を呼ぶと、EF Coreが必要なUPDATE文を発行します。EF Coreの変更追跡は、クエリと更新に関係するエンティティ状態を管理する仕組みです。
マイグレーションは、C#のモデル変更に合わせてデータベーススキーマを変更する機能です。開発中にプロパティを追加した場合、マイグレーションを作成してデータベースに反映できます。
3-2. EF Coreのメリット:開発効率と保守性の高さ
EF Coreの最大のメリットは、開発効率の高さです。単純なCRUDであれば、SQLをほとんど書かずに実装できます。C#のクラスとLINQを中心に開発できるため、Visual StudioやRiderなどのIDEによる補完も効きやすく、型安全なコードを書きやすいです。
また、テーブル構造とC#のモデルを近い形で管理できるため、コードの見通しがよくなります。チーム開発でも、エンティティクラスやDbContextを見れば、どのようなデータを扱っているか把握しやすくなります。
さらに、ASP.NET Coreとの統合がしやすい点もメリットです。DIコンテナにDbContextを登録し、ControllerやServiceから注入して使う構成が一般的です。
3-3. EF Coreのデメリット:パフォーマンスと学習コスト
EF Coreは便利ですが、万能ではありません。
まず、SQLを自動生成するため、開発者が生成SQLを意識しないまま実装すると、非効率なクエリになることがあります。特に、関連データの読み込み、複雑なLINQ、集計処理では注意が必要です。
また、EF Coreには学ぶべき概念が多くあります。
DbContext
DbSet
Entity
Change Tracking
Migration
Include
Lazy Loading
Fluent API
Tracking / No Tracking
初心者にとっては、最初の学習コストがやや高く感じられるかもしれません。
ただし、C#で中長期的にWebアプリや業務システムを作るなら、EF Coreの知識は非常に役立ちます。
3-4. EF Coreが向いているケース
EF Coreが向いているのは、開発効率と保守性を重視するプロジェクトです。
たとえば、次のようなケースではEF Coreがおすすめです。
ASP.NET Coreで新規Webアプリを作る
CRUD中心の業務システムを作る
テーブル設計とC#モデルを一緒に管理したい
チームで一定のルールに沿って開発したい
SQLよりもC#コード中心で実装したい
マイグレーションでDBスキーマを管理したい
特に初心者や小〜中規模のWebアプリでは、EF Coreを選ぶと開発を進めやすいです。
3-5. EF Coreが向いていないケース
EF Coreが向いていないのは、SQLを細かく制御したいケースや、非常に高いパフォーマンスが求められるケースです。
たとえば、複雑な検索画面、重い集計処理、大量データを扱うバッチ処理では、EF CoreのLINQよりもSQLを直接書いたほうが分かりやすい場合があります。
また、既存データベースの構造が複雑で、テーブル設計をアプリケーション側から変更できない場合も注意が必要です。EF Coreでも既存DBへの対応は可能ですが、設計によってはマッピングが複雑になります。
4. Dapperとは?特徴・メリット・デメリット
4-1. Dapperの基本機能:SQL実行とオブジェクトマッピング
Dapperは、SQLの実行結果をC#のオブジェクトにマッピングするMicro ORMです。
たとえば、次のようにSQLを書いてデータを取得できます。
C#var users = await connection.QueryAsync<User>(
"SELECT Id, Name, Email FROM Users WHERE Name LIKE @Name",
new { Name = "%佐藤%" }
);
DapperはSQL自体を自動生成するのではなく、開発者が書いたSQLを実行し、その結果をUserクラスに詰め替えてくれます。NuGetでもDapperは高性能なMicro ORMとして紹介され、SQL Server、MySQL、SQLiteなど複数のデータベースに対応するライブラリとして説明されています。
4-2. Dapperのメリット:高速・軽量・SQLを細かく制御できる
Dapperのメリットは、高速で軽量なことです。EF Coreのような変更追跡やマイグレーションなどの大きな機能を持たないため、処理がシンプルです。
また、SQLを自分で書くため、実行されるSQLが明確です。SQLのチューニングをしたい場合や、データベース固有の機能を使いたい場合にも向いています。
たとえば、次のようなケースではDapperの強みが出ます。
複雑なJOINを含む検索
集計クエリ
レポート出力
大量データの読み取り
ストアドプロシージャの呼び出し
SQL ServerやPostgreSQL固有機能の活用
「C#からSQLを安全かつ簡潔に実行したい」という用途に、Dapperは非常に適しています。
4-3. Dapperのデメリット:SQL管理と実装量が増えやすい
Dapperのデメリットは、SQLを自分で管理する必要があることです。
小規模なうちは分かりやすいのですが、画面や機能が増えてくると、SQL文字列があちこちに散らばりやすくなります。更新処理や登録処理も自分でSQLを書く必要があるため、EF Coreよりコード量が増えることがあります。
また、テーブル構造が変わった場合、SQL文字列も手作業で修正する必要があります。C#のプロパティ名を変更しても、SQL文字列のカラム名まではIDEが安全に追跡してくれないことが多いため、リファクタリング時に注意が必要です。
4-4. Dapperが向いているケース
Dapperが向いているのは、SQLを明示的に書きたいプロジェクトです。
たとえば、次のようなケースではDapperがおすすめです。
パフォーマンスを重視したい
SQLを細かくチューニングしたい
複雑な検索・集計が多い
既存DBやストアドプロシージャを活用したい
ORMの自動生成SQLに任せたくない
ADO.NETのコード量を減らしたい
Dapperは、SQLに慣れている開発者にとって扱いやすいライブラリです。
4-5. Dapperが向いていないケース
Dapperが向いていないのは、SQLを書きたくない場合や、CRUD処理を素早く実装したい場合です。
たとえば、管理画面のように単純な登録・更新・削除が多いシステムでは、Dapperだけで実装するとSQLの量が増えます。変更追跡やマイグレーションも標準では持たないため、設計や運用を自分たちで考える必要があります。
初心者がいきなりDapperから入ると、C# ORMというより「C#でSQLをきれいに実行するライブラリ」として学ぶことになります。そのため、ORM全体の考え方を学びたいなら、まずEF Coreを学ぶほうが分かりやすいです。
5. Entity Framework CoreとDapperの違いを比較
5-1. 開発効率の違い
開発効率を重視するなら、基本的にはEF Coreが有利です。
EF Coreでは、エンティティクラスとDbContextを用意すれば、LINQでデータ取得を書けます。追加・更新・削除も、オブジェクトを操作してSaveChangesAsync()を呼ぶ形で実装できます。
一方、DapperはSQLを自分で書く必要があります。単純なSELECTなら短く書けますが、INSERT、UPDATE、DELETE、複数テーブルの保存処理などが増えると、実装量はEF Coreより多くなりやすいです。
5-2. パフォーマンスの違い
パフォーマンスを重視するなら、Dapperが有利な場面が多いです。
DapperはMicro ORMであり、SQLを実行して結果をオブジェクトにマッピングすることに特化しています。余計な機能が少ないため、読み取り処理では高速に動作しやすいです。
EF Coreも通常のWebアプリや業務システムでは十分なパフォーマンスを発揮します。しかし、変更追跡やLINQからSQLへの変換などの仕組みがあるため、Dapperよりオーバーヘッドが大きくなることがあります。
ただし、実際の速度差はアプリケーションの設計、SQL、インデックス、データ量、ネットワーク、DBサーバーの性能にも左右されます。「Dapperだから必ず速い」「EF Coreだから遅い」と単純に判断するのではなく、必要に応じて計測することが重要です。
5-3. SQLの書き方・制御しやすさの違い
SQLを細かく制御したいならDapperが向いています。
Dapperでは、開発者が書いたSQLがそのまま実行されます。そのため、JOIN、サブクエリ、集計関数、ウィンドウ関数、DB固有構文などを自由に使いやすいです。
EF CoreではLINQを使ってクエリを書きます。簡単な検索であれば読みやすく型安全ですが、複雑なSQLをLINQで表現しようとすると、かえって分かりづらくなることがあります。ただし、EF Coreでもリレーショナルデータベースに対してSQLクエリを直接実行できます。公式ドキュメントでも、LINQで表現できないクエリや非効率なSQLが生成される場合にSQLクエリが有用だと説明されています。
5-4. 学習コストの違い
初心者にとって、最初の学習コストはEF Coreのほうが高めです。DbContext、エンティティ、マイグレーション、変更追跡、リレーション、Includeなど、理解すべき概念が多いからです。
一方、Dapperは「SQLを書いて、結果をC#のクラスに入れる」という考え方なので、SQLを知っている人には分かりやすいです。ただし、SQL初心者の場合は、Dapperを学ぶ前にSELECT、JOIN、WHERE、ORDER BY、GROUP BYなどの基礎を身につける必要があります。
C#初心者で、かつSQLにもあまり慣れていない場合は、EF Coreから学ぶほうがアプリ全体を作るイメージをつかみやすいです。
5-5. 保守性・チーム開発での違い
保守性は、プロジェクトの性質によって評価が変わります。
EF Coreは、エンティティクラスやDbContextを中心にデータアクセスを整理しやすく、チームでルールを統一しやすいです。マイグレーションを使えば、DBスキーマの変更履歴もコードとして管理できます。
Dapperは、SQLの書き方や置き場所を決めておかないと、SQLがServiceやControllerに散らばって保守しづらくなることがあります。そのため、Dapperを使う場合は、RepositoryクラスやQueryクラスを用意し、SQLの管理場所を明確にすることが大切です。
5-6. トランザクション・複雑なクエリでの違い
トランザクション処理は、EF CoreでもDapperでも対応できます。
EF Coreでは、SaveChangesAsync()が通常1回のトランザクションとして扱われます。複数の処理をまとめたい場合は、明示的にトランザクションを開始することもできます。
Dapperでは、ADO.NETのDbTransactionを使ってトランザクションを制御します。SQLを明示的に書くため、複雑な更新処理やストアドプロシージャとの組み合わせでは分かりやすい場合があります。
複雑なクエリについては、Dapperのほうが自然に書けることが多いです。EF Coreでも複雑なLINQは書けますが、生成されるSQLを確認しながら実装する必要があります。
5-7. マイグレーション対応の違い
マイグレーション機能はEF Coreの大きな強みです。
EF Coreでは、エンティティクラスの変更に応じてマイグレーションファイルを作成し、データベーススキーマを更新できます。チーム開発では、マイグレーションファイルをソース管理に含めることで、DB変更の履歴を共有できます。EF Core公式ドキュメントでも、チーム環境では複数の開発者が同時期にマイグレーションを追加することで問題が起こり得るため、管理が重要だと説明されています。
Dapperには標準のマイグレーション機能はありません。そのため、DbUp、FluentMigrator、Liquibase、Flywayなど別のツールを組み合わせるか、SQLスクリプトを自分たちで管理する必要があります。
5-8. 比較表:EF CoreとDapperはどちらを選ぶべきか
| 比較項目 | Entity Framework Core | Dapper |
|---|---|---|
| 種類 | フル機能ORM | Micro ORM |
| 基本スタイル | LINQ・オブジェクト中心 | SQL直書き中心 |
| 開発効率 | 高い | SQL量が増えやすい |
| パフォーマンス | 通常用途では十分 | 高速・軽量 |
| SQL制御 | 自動生成SQL中心 | 自分で完全に書ける |
| 学習コスト | ORM概念が多い | SQL経験者には低め |
| 保守性 | ルール化しやすい | SQL管理設計が重要 |
| マイグレーション | 標準対応 | 標準では非対応 |
| CRUD | 得意 | 書けるがSQLが必要 |
| 複雑な検索・集計 | LINQが複雑になる場合あり | 得意 |
| 初心者向け | おすすめ | SQL経験があるならおすすめ |
結論として、初心者やCRUD中心のWebアプリではEF Coreがおすすめです。パフォーマンスやSQL制御を重視する場合はDapperが向いています。
6. C# ORMの選び方:目的別おすすめ
6-1. 初心者・小〜中規模WebアプリならEF Core
C# ORMを初めて使う初心者には、まずEF Coreがおすすめです。
理由は、ASP.NET Coreとの相性がよく、情報量も多く、CRUD処理を効率よく実装できるからです。C#のクラス、DbContext、LINQを使ってデータアクセスを学べるため、C#らしい開発スタイルを身につけやすいです。
小〜中規模のWebアプリであれば、EF Coreのパフォーマンスで困ることは多くありません。まずはEF Coreで作り、必要な箇所だけ最適化する方針が現実的です。
6-2. パフォーマンス重視ならDapper
パフォーマンスを重視するなら、Dapperを検討しましょう。
特に、読み取り専用の検索処理、一覧表示、レポート出力、大量データの取得などではDapperが有力です。SQLを自分で最適化できるため、インデックスを意識したクエリやDB固有の書き方も活用しやすいです。
ただし、パフォーマンスだけで全体をDapperにする必要はありません。通常のCRUDはEF Core、重い検索だけDapperという併用も有効です。
6-3. SQLを細かく書きたいならDapper
SQLを自分で書きたい開発者にはDapperが向いています。
EF CoreではLINQからSQLが生成されますが、DapperではSQLをそのまま書けます。そのため、実行されるSQLを完全に把握しやすく、DBAと協力してSQLをチューニングする場合にも扱いやすいです。
SQL Server、PostgreSQL、MySQLなどの固有機能を活用したい場合も、Dapperのほうが素直に実装できることがあります。
6-4. CRUD中心の業務システムならEF Core
CRUD中心の業務システムでは、EF Coreが向いています。
たとえば、社員管理、顧客管理、商品管理、在庫管理、受注管理などは、登録・更新・削除・一覧表示が中心です。このようなシステムでは、SQLを毎回書くよりも、EF Coreでエンティティを操作するほうが開発効率が高くなりやすいです。
また、モデル変更に合わせてマイグレーションを管理できるため、開発中の仕様変更にも対応しやすいです。
6-5. 複雑な検索・集計処理が多い場合の選び方
複雑な検索や集計が多い場合は、Dapperを優先的に検討するとよいでしょう。
たとえば、次のような処理です。
複数テーブルをまたぐ集計
売上レポート
月次・年次集計
動的検索条件が多い一覧画面
ウィンドウ関数を使うSQL
CTEを使うSQL
EF Coreでも実装できる場合はありますが、LINQが複雑になりすぎると可読性が下がります。複雑なクエリはSQLで書いたほうが、意図が明確になりやすいです。
6-6. 既存データベースを使う場合の選び方
既存データベースを使う場合は、DB構造の複雑さによって選び方が変わります。
テーブル設計が比較的シンプルで、C#のクラスに自然に対応できるならEF Coreでも問題ありません。EF Coreには既存DBからDbContextやエンティティを生成するリバースエンジニアリング機能もあります。EF CoreのDesignパッケージは、マイグレーション管理や既存スキーマからDbContext・エンティティ型をスキャフォールドする設計時タスクで使われます。
一方、既存DBが複雑で、ストアドプロシージャや独自SQLが多い場合はDapperが向いています。既存SQLを活かしやすく、無理にORMのモデルへ合わせる必要がありません。
6-7. EF CoreとDapperを併用する選択肢
実務では、EF CoreとDapperを併用する選択肢もあります。
たとえば、次のような構成です。
通常のCRUD:EF Core
複雑な検索:Dapper
重い一覧画面:Dapper
登録・更新処理:EF Core
レポート出力:Dapper
このように使い分けると、EF Coreの開発効率とDapperのSQL制御・高速性を両立できます。
ただし、併用する場合は設計ルールが必要です。どの処理でEF Coreを使い、どの処理でDapperを使うのかを決めておかないと、データアクセス層が分かりづらくなります。
7. 初心者向け:EF CoreとDapperの簡単な実装イメージ
7-1. EF Coreでデータを取得する基本コード
EF Coreでは、まずエンティティクラスを用意します。
C#public class User
{
public int Id { get; set; }
public string Name { get; set; } = "";
public string Email { get; set; } = "";
}
次に、DbContextを作成します。
C#public class AppDbContext : DbContext
{
public DbSet<User> Users => Set<User>();
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{
}
}
データを取得するコードは次のようになります。
C#public class UserService
{
private readonly AppDbContext _context;
public UserService(AppDbContext context)
{
_context = context;
}
public async Task<List<User>> GetUsersAsync()
{
return await _context.Users
.Where(u => u.Name.Contains("佐藤"))
.ToListAsync();
}
}
EF Coreでは、SQLを直接書かずにLINQで取得条件を表現できます。
7-2. Dapperでデータを取得する基本コード
Dapperでは、SQLを自分で書いて実行します。
C#public class UserRepository
{
private readonly IDbConnection _connection;
public UserRepository(IDbConnection connection)
{
_connection = connection;
}
public async Task<IEnumerable<User>> GetUsersAsync()
{
var sql = @"
SELECT Id, Name, Email
FROM Users
WHERE Name LIKE @Name
";
return await _connection.QueryAsync<User>(
sql,
new { Name = "%佐藤%" }
);
}
}
Dapperのコードでは、実行されるSQLが明確です。SQLを読み慣れている人にとっては、EF CoreのLINQより分かりやすい場合があります。
7-3. EF CoreとDapperのコード量・読みやすさの違い
単純な検索では、EF CoreもDapperもコード量に大きな差はありません。
EF CoreはC#のLINQで書けるため、エンティティとのつながりが分かりやすいです。プロパティ名の補完も効き、リファクタリングにも比較的強いです。
DapperはSQLが見えるため、データベース視点では読みやすいです。ただし、SQL文字列内のカラム名はC#の型チェックを受けにくいため、テーブル変更時には注意が必要です。
更新処理やリレーションを含む処理が増えるほど、EF Coreのコード量は少なくなりやすく、DapperはSQL管理の工夫が必要になります。
7-4. ASP.NET Coreで使う場合の構成例
ASP.NET CoreでEF Coreを使う場合、一般的にはProgram.csでDbContextをDI登録します。
C#builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
ServiceやControllerでは、コンストラクタインジェクションでAppDbContextを受け取ります。
C#public class UsersController : Controller
{
private readonly AppDbContext _context;
public UsersController(AppDbContext context)
{
_context = context;
}
}
Dapperを使う場合は、IDbConnectionを生成するFactoryを用意する構成がよく使われます。
C#public interface IDbConnectionFactory
{
IDbConnection CreateConnection();
}
C#public class SqlConnectionFactory : IDbConnectionFactory
{
private readonly string _connectionString;
public SqlConnectionFactory(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("DefaultConnection")!;
}
public IDbConnection CreateConnection()
{
return new SqlConnection(_connectionString);
}
}
Dapperでは接続の生成や破棄のルールをチームで統一しておくことが大切です。
7-5. Repositoryパターンを使うべきか
Repositoryパターンを使うべきかは、プロジェクト規模によります。
小規模なアプリでは、EF CoreのDbContext自体がRepositoryに近い役割を持つため、無理にRepositoryを作る必要はありません。過剰に抽象化すると、かえってコードが複雑になる場合があります。
一方、中規模以上のアプリや、Dapperを使う場合はRepositoryを用意するとSQLの置き場所を整理しやすくなります。
目安としては、次のように考えるとよいです。
| ケース | Repositoryの必要性 |
|---|---|
| 小規模なEF Coreアプリ | 必須ではない |
| 中規模以上のEF Coreアプリ | Service層との分離目的で検討 |
| Dapper中心のアプリ | SQL管理のために有効 |
| EF CoreとDapper併用 | データアクセス方針を整理するために有効 |
Repositoryパターンは「必ず使うもの」ではなく、保守性を高めるために必要な場合に導入するものです。
8. C# ORM導入時によくある失敗と対策
8-1. ORMを使えばSQLを知らなくてよいと思ってしまう
C# ORM導入時によくある失敗は、「ORMを使えばSQLを知らなくてよい」と考えてしまうことです。
EF Coreを使えばSQLを書かずに多くの処理を実装できますが、最終的にはデータベース上でSQLが実行されます。生成されたSQLが非効率であれば、アプリケーションのパフォーマンスは低下します。
対策として、開発中はログを有効にして、EF CoreがどのようなSQLを発行しているか確認しましょう。特に一覧画面、検索画面、関連データの読み込みではSQL確認が重要です。
8-2. EF CoreでN+1問題に気づかない
EF Coreで注意したい代表的な問題がN+1問題です。
N+1問題とは、最初に1回のクエリで親データを取得し、その後、各レコードごとに関連データを取得するクエリが大量に発行される問題です。たとえば、100件の注文を取得したあと、各注文の明細を1件ずつ取得すると、合計101回のクエリが発行される可能性があります。
対策として、必要な関連データはIncludeで明示的に読み込む、または必要な列だけをSelectで投影する方法があります。EF CoreではIncludeを使って関連データをクエリ結果に含めることができます。
8-3. DapperでSQLが散らばって保守しづらくなる
Dapperでよくある失敗は、SQL文字列がControllerやServiceに散らばることです。
最初は手軽に書けますが、機能が増えると「同じようなSQLが複数箇所にある」「修正漏れが起きる」「どこでどのテーブルを使っているか分からない」という状態になりがちです。
対策として、SQLはRepositoryやQueryServiceに集約しましょう。また、複雑なSQLは定数、別ファイル、クエリ専用クラスなどに分けると管理しやすくなります。
8-4. パフォーマンスだけでORMを選んでしまう
「Dapperは速いから、全部Dapperにする」という判断は危険です。
確かにDapperは高速ですが、CRUD処理が多い業務システムでは、SQLを大量に書くことによる開発コストや保守コストが大きくなる場合があります。
ORM選定では、パフォーマンスだけでなく、次の観点も重要です。
| 観点 | 確認すべきこと |
|---|---|
| 開発効率 | 少ないコードで実装できるか |
| 保守性 | チームで理解しやすいか |
| 学習コスト | メンバーが使いこなせるか |
| SQL制御 | 複雑なSQLが必要か |
| 運用 | DB変更をどう管理するか |
パフォーマンスが必要な箇所だけDapperを使い、それ以外はEF Coreを使う判断も有効です。
8-5. チームのスキルや運用体制を考慮しない
C# ORM選びでは、チームのスキルも重要です。
SQLに強いメンバーが多いチームなら、Dapperは扱いやすい選択肢です。一方、C#中心で開発したいチームや、ORMに慣れているメンバーが多いチームならEF Coreが向いています。
また、DBスキーマ変更の運用も考える必要があります。EF Coreのマイグレーションを使うのか、SQLスクリプトをDBAが管理するのか、CI/CDでどのように反映するのかを事前に決めておきましょう。
9. C# ORMに関するよくある質問
9-1. C#で一番おすすめのORMはどれですか?
初心者や一般的なWebアプリ開発では、Entity Framework Coreがおすすめです。
理由は、Microsoft公式のORMであり、ASP.NET Coreとの相性がよく、情報量も多いからです。LINQ、変更追跡、マイグレーションなど、アプリ開発に必要な機能が一通りそろっています。
ただし、SQLを細かく制御したい場合や、パフォーマンスを重視する処理ではDapperがおすすめです。
9-2. Entity Framework CoreとDapperはどちらが速いですか?
一般的にはDapperのほうが高速になりやすいです。
DapperはSQL実行とオブジェクトマッピングに特化したMicro ORMで、EF Coreのような変更追跡やLINQ変換の仕組みが少ないためです。
ただし、実際のパフォーマンスはSQL、インデックス、データ量、DB設計、ネットワークなどに大きく左右されます。通常のCRUD中心のWebアプリであれば、EF Coreでも十分なケースが多いです。
9-3. 初心者はEF CoreとDapperのどちらから学ぶべきですか?
初心者はEF Coreから学ぶのがおすすめです。
EF Coreを学ぶと、C#のクラスとデータベーステーブルを対応付けるORMの考え方を理解できます。また、ASP.NET Coreの入門教材でもEF Coreが使われることが多く、学習しやすいです。
ただし、SQLの基礎も必ず学びましょう。Dapperを使う場合はもちろん、EF Coreを使う場合でもSQLの理解は重要です。
9-4. EF CoreとDapperは併用できますか?
EF CoreとDapperは併用できます。
実務では、通常のCRUDはEF Core、複雑な検索や高速化したい処理はDapper、という使い分けがよくあります。
併用する場合は、同じ接続文字列を使う、トランザクション境界を明確にする、データアクセス層の責務を整理する、といった設計が重要です。
9-5. C#でORMを使わずSQL直書きでも問題ありませんか?
問題ありません。
C#でORMを使わず、ADO.NETやDapperでSQLを直接書く設計も十分に実用的です。特に、SQLを厳密に管理したいシステムや、DBAがSQLをレビューする運用では、SQL直書きのほうが適している場合もあります。
ただし、SQL直書きでは、コード量、マッピング、SQL管理、テーブル変更時の修正漏れに注意が必要です。開発効率や保守性を重視するなら、EF CoreのようなORMを検討するとよいでしょう。
9-6. .NET FrameworkでもEF CoreやDapperは使えますか?
Dapperは.NET Frameworkでも利用しやすいライブラリです。NuGet上のDapper 2.1系では、.NET Framework 4.6.1以上を対象にしたパッケージ情報が確認できます。
EF Coreについては、バージョンによって対応状況が異なります。古いEF Coreでは.NET Standard 2.0経由で.NET Framework 4.6.1に対応していた時期がありますが、現在のEF Coreは主にモダンな.NETを対象にしています。MicrosoftのEF Core対応プラットフォーム情報でも、現代的な.NET実装への対応が中心で、古い.NET実装には注意が必要だと説明されています。
.NET Frameworkの既存アプリでORMを使う場合は、EF Coreのバージョン互換性を確認するか、従来のEntity Framework 6、Dapper、ADO.NETを検討するとよいでしょう。
まとめ
C# ORMを選ぶときは、「どのライブラリが一番優れているか」ではなく、「プロジェクトの目的に合っているか」で判断することが重要です。
Entity Framework Coreは、C#のオブジェクト中心で開発できるフル機能ORMです。LINQ、変更追跡、マイグレーションなどが使えるため、初心者やCRUD中心のWebアプリ、業務システムに向いています。
Dapperは、高速で軽量なMicro ORMです。SQLを自分で書いて実行するため、複雑な検索、集計、レポート出力、パフォーマンス重視の処理に向いています。
選び方の目安は次のとおりです。
| 目的 | おすすめ |
|---|---|
| 初心者がC# ORMを学ぶ | EF Core |
| 小〜中規模のWebアプリを作る | EF Core |
| CRUD中心の業務システムを作る | EF Core |
| SQLを細かく制御したい | Dapper |
| パフォーマンスを重視したい | Dapper |
| 複雑な検索・集計が多い | Dapper |
| 開発効率と高速化を両立したい | EF CoreとDapperの併用 |
C# ORMで迷ったら、まずはEF Coreを基本に考え、パフォーマンスやSQL制御が必要な部分にDapperを使う方針がおすすめです。ORMはSQLを隠すためのものではなく、C#でデータベース操作を効率よく、安全に、保守しやすくするための道具です。用途に合わせて適切に選べば、C#開発の生産性を大きく高められます。

