This project is a REST API designed to compare the performance of two of the most popular database access technologies in the .NET ecosystem: Dapper and Entity Framework Core.
The main goal of this project is to provide developers with concrete data that highlights the trade-off between ease of use and raw performance.
| Scenario | EF Core Time | Dapper Time |
|---|---|---|
| Data Insertion | 6736 ms | 395 ms |
| Generate Orders | 60607 ms | - |
| Report Top Sellers | 255 ms | 224 ms |
Entity Framework Core (6736 ms)

Entity Framework Core (60607 ms)

Entity Framework Core (255 ms)

This benchmark project focuses on two critical scenarios where ORM performance differences are most noticeable:
-
Bulk Data Insertion:
A write-heavy scenario where tens of thousands of records are inserted into the database in a single operation.
This test measures the overhead of EF Core’s change tracking mechanism compared to Dapper’s raw performance withSqlBulkCopy. -
Complex Read Query (Reporting):
A read-heavy scenario involving multiple tableJOINs, grouping (GROUP BY), and aggregation (SUM).
This test measures the cost of EF Core translating LINQ to SQL versus Dapper executing a hand-optimized SQL query directly.
- Framework: .NET 8
- API: ASP.NET Core Web API
- Database: SQL Server
- ORM / Micro-ORM:
- Entity Framework Core
- Dapper
- Data Generation: Bogus (for realistic fake data)
Follow these steps to run the project locally and perform the benchmarks.
-
Clone the Repository:
git clone https://github.com/kayamuhammet/Dapper-vs-EFCore.git cd backend -
Configure Database Connection: Open
appsettings.Development.jsonand update theConnectionStringssection with your SQL Server instance details.{ "ConnectionStrings": { "DefaultConnection": "Server=(LocalServerName)\\SQLEXPRESS;Database=DbName;Trusted_Connection=True;TrustServerCertificate=True;" } }Note: Replace
Serverwith your own SQL Server name. The database will be created automatically in the next step. -
Create and Update Database: Run EF Core migrations to create the schema.
dotnet ef database update
-
Run the Application:
dotnet run
The API will start on
http://localhost:5151. Swagger UI is available athttp://localhost:5151/swagger.
For meaningful results, it’s recommended to run the endpoints in the following order.
-
Step 1: Generate Product Data Create initial product data for reporting queries. The Dapper endpoint is significantly faster for this step.
POST /dataimport/dapper-bulk-insert?count=10000
-
Step 2: Generate Orders Create a large number of orders and order items linked to the products. This may take some time.
POST /dataimport/generate-orders?orderCount=5000&maxItemsPerOrder=5
-
Step 3: Compare Reporting Endpoints With enough data in place, run both reporting endpoints to observe performance differences.
GET /reports/topsellers-efcoreGET /reports/topsellers-dapper
All endpoints return execution time in milliseconds.
| Method | Endpoint | Description |
|---|---|---|
POST |
/dataimport/efcore-bulk-insert |
Inserts the specified count of products using EF Core. |
POST |
/dataimport/dapper-bulk-insert |
Inserts the specified count of products using Dapper + SqlBulkCopy. |
POST |
/dataimport/generate-orders |
Generates random orders based on existing products. |
| Method | Endpoint | Description |
|---|---|---|
GET |
/reports/topsellers-efcore |
Reports top 20 products by revenue using EF Core LINQ query. |
GET |
/reports/topsellers-dapper |
Reports top 20 products by revenue using raw SQL with Dapper. |
When running the tests, you should expect the following:
-
Bulk Insert: Dapper (with
SqlBulkCopy) will be significantly faster than EF Core, because EF Core performs change tracking for every inserted entity, while Dapper writes directly to the database. -
Complex Query: Dapper will also be faster here, although the difference is less dramatic. Dapper avoids the LINQ-to-SQL translation and materialization overhead of EF Core.
Contributions are welcome! Please open an issue or submit a pull request.
This project is licensed under the MIT License.
Bu proje, .NET ekosisteminin en popüler iki veritabanı erişim teknolojisi olan Dapper ve Entity Framework Core'un performansını karşılaştırmak için tasarlanmış bir REST API'ıdır.
Projenin temel amacı, geliştiricilere "kullanım kolaylığı" ile "ham performans" arasındaki dengeyi somut verilerle göstermektir.
Bu benchmark projesi, ORM'lerin performans farklarının en net şekilde ortaya çıktığı iki kritik senaryoya odaklanır:
-
Toplu Veri Ekleme (Bulk Data Insertion): Tek bir işlemde on binlerce kaydın veritabanına yazıldığı, yazma ağırlıklı (write-heavy) bir senaryodur. Bu test, EF Core'un change tracking (değişiklik izleme) mekanizmasının getirdiği ek yükü, Dapper'ın
SqlBulkCopyile entegre edilmiş ham performansına karşı ölçer. -
Karmaşık Raporlama Sorgusu (Complex Read Query): Birden fazla tablonun
JOINile birleştirildiği, gruplama (GROUP BY) ve toplama (SUM) fonksiyonlarının kullanıldığı, okuma ağırlıklı (read-heavy) bir senaryodur. Bu test, EF Core'un LINQ sorgularını SQL'e çevirme maliyetini, Dapper ile çalıştırılan optimize edilmiş ham SQL sorgusunun hızına karşı ölçer.
- Framework: .NET 8
- API: ASP.NET Core Web API
- Veritabanı: SQL Server
- ORM / Micro-ORM:
- Entity Framework Core
- Dapper
- Veri Üretimi: Bogus (Gerçekçi sahte veri üretimi için)
Projeyi yerel makinenizde çalıştırmak ve test etmek için aşağıdaki adımları izleyin.
-
Projeyi Klonlayın:
git clone https://github.com/kayamuhammet/Dapper-vs-EFCore.git cd backend -
Veritabanı Bağlantısını Yapılandırın:
appsettings.Development.jsondosyasını açın veConnectionStringsbölümünü kendi SQL Server örneğinizin bilgileriyle güncelleyin.{ "ConnectionStrings": { "DefaultConnection": "Server=(LocalServerName)\\SQLEXPRESS;Database=DbName;Trusted_Connection=True;TrustServerCertificate=True;" } }Not:
Serveradını kendi sunucu adınızla değiştirmeyi unutmayın. Veritabanı, bir sonraki adımda otomatik olarak oluşturulacaktır. -
Veritabanını Oluşturun ve Güncelleyin: Proje kök dizininde bir terminal açın ve EF Core migration komutlarını çalıştırarak veritabanı şemasını oluşturun.
dotnet ef database update
-
Uygulamayı Çalıştırın:
dotnet run
Uygulama varsayılan olarak
http://localhost:5151portlarında çalışmaya başlayacaktır. Swagger arayüzünehttp://localhost:5151/swaggeradresinden erişebilirsiniz.
En anlamlı sonuçları elde etmek için endpoint'leri aşağıdaki sırayla çalıştırmanız önerilir.
-
Adım 1: Ürün Verilerini Oluşturun İlk olarak, raporlama sorgularında kullanılacak temel ürün verilerini oluşturun. Dapper endpoint'i bu işlem için çok daha hızlıdır.
POST /dataimport/dapper-bulk-insert?count=10000
-
Adım 2: Sipariş Verilerini Oluşturun Oluşturulan ürünlere bağlı, yüksek sayıda sipariş ve sipariş kalemi verisi üretin. Bu işlem biraz zaman alabilir.
POST /dataimport/generate-orders?orderCount=5000&maxItemsPerOrder=5
-
Adım 3: Raporlama Endpoint'lerini Karşılaştırın Veritabanı artık yeterli veri içerdiğine göre, her iki raporlama endpoint'ini de çalıştırarak performans farkını gözlemleyebilirsiniz.
GET /reports/topsellers-efcoreGET /reports/topsellers-dapper
Tüm endpoint'ler, işlemin ne kadar sürdüğünü milisaniye cinsinden gösteren bir yanıt döner.
| Method | Endpoint | Açıklama |
|---|---|---|
POST |
/dataimport/efcore-bulk-insert |
count parametresi kadar ürünü EF Core ile veritabanına ekler. |
POST |
/dataimport/dapper-bulk-insert |
count parametresi kadar ürünü Dapper ve SqlBulkCopy ile ekler. |
POST |
/dataimport/generate-orders |
Mevcut ürünleri kullanarak orderCount kadar rastgele sipariş oluşturur. |
| Method | Endpoint | Açıklama |
|---|---|---|
GET |
/reports/topsellers-efcore |
En çok ciro yapan ilk 20 ürünü EF Core LINQ sorgusu ile raporlar. |
GET |
/reports/topsellers-dapper |
En çok ciro yapan ilk 20 ürünü Dapper ve ham SQL sorgusu ile raporlar. |
Testleri çalıştırdığınızda aşağıdaki sonuçları gözlemlemeyi bekleyebilirsiniz:
-
Toplu Ekleme: Dapper (
SqlBulkCopykullanarak), EF Core'dan önemli ölçüde daha hızlı olacaktır. Bunun temel nedeni, Dapper'ın veriyi doğrudan veritabanına aktarması, EF Core'un ise eklediği her bir nesne için bir change tracking mekanizması çalıştırmasıdır. -
Karmaşık Sorgu: Dapper, bu senaryoda da EF Core'dan daha hızlı olacaktır. Fark toplu eklemedeki kadar dramatik olmasa da, Dapper'ın doğrudan optimize edilmiş bir SQL sorgusunu çalıştırması, EF Core'un LINQ'yu SQL'e çevirme ve sonuçları nesnelere eşleme (materialization) adımlarından kaynaklanan ek maliyeti ortadan kaldırır.
Katkıda bulunmak isterseniz, lütfen bir "issue" açın veya "pull request" gönderin.
Bu proje MIT Lisansı altında lisanslanmıştır.

