Dapper über .NET Standard 2.0 auf .NET Core

Fortschritt ist, das Primitive zu entwickeln
und das Entwickelte zu Vereinfachen. – Lothar Wassermann

Es geht um Dapper und ich führe ein bisschen aus. Bei den ersten Marketing-Präsentationen zu Entity Framework Core (EF Core) wurde von Microsoft auch vollmundig versprochen, dass EF Core in Sachen Performance locker mit Dapper mithalten kann.

Für mich war das Grund genug die Aussage mit einem einfachen Test zu überprüfen, welcher 2’000 Bücher lädt. Dieses Performance-Beispiel habe ich auf Github.

Meine Erkenntnisse daraus waren sehr interessant. Ein beliebter Ansatz bei der Performance-Optimierung beim Entity Framework ist die Verwendung von AsNoTracking. Gerade bei Webanwendungen macht es wenig Sinn im DbContext einen Firstlevel-Cache aufzubauen, wenn dieser nach Beendigung der Abfrage wieder zerstört wird.

Mit EF Core gibt es da ein interessantes Phänomen:

EF6 Datenbank mit Testdaten erstellt.
EF Core Datenbank mit Testdaten erstellt.
Query-Warmup für Dapper ausgeführt


Abfragedauer Lade 2000 Bücher mit Entity Framework 6: 838 ms
Abfragedauer Lade 2000 Bücher mit Entity Framework 6 AsNoTracking: 7 ms

Abfragedauer Lade 2000 Bücher mit Entity Framework Core: 6 ms
Abfragedauer Lade 2000 Bücher mit Entity Framework Core AsNoTracking: 18 ms

Abfragedauer Lade 2000 Bücher mit Dapper: 2 ms

Ganz klar ist EF Core schneller unterwegs als das klassische Entity Framework 6, schneller als die Abfrage mit AsNoTracking von EF 6. Interessant dabei ist aber, dass AsNoTracking bei EF Core drei mal mehr Zeit benötigt als die normale Abfrage. Dapper ist ganz klar der Sieger mit zwei Millisekunden.

Da ich in der Vergangenheit auch Lösungen realisierte, wo ein OR-Mapper wie Entity Framework nicht die beste Lösung gewesen wäre, gehört auch Dapper in meinen Stack.

Mit .NET Standard 2.0 existieren nun rund 32’000 Programmierschnittstellen und viele Nuget-Pakete sollen bereits kompatibel sein. Was liegt also näher? Genau, ich teste ob Dapper mit .NET Core 2.0 in einer .NET Standard Bibliothek funktioniert.

Mein Vorgehen war dabei folgendes:

  1. .NET Core 2.0 Konsolenanwendung erstellt
  2. eine .NET Standard Bibliothek hinzugefügt
  3. Package Dapper der .NET Standard Bibliothek hinzugefügt
  4. Eine .NET Core Testprojekt
  5. Eine Routine aus meinen Performance-Beispiel übernommen.

Der Test hat folgenden Aufbau:

[TestClass]
public class DapperNetCoreTest
{
  [TestMethod]
  public void GetBuecher_RequestAExistingBookList_ReturnsCollection()
  {
    // Vorbedingung: EfPerformance einmalig laufen, lassen.
    // ToDo: Test überarbeiten
    IDbConnection conn =
      new SqlConnection(
        "data source=.;initial catalog=EfPerf2;User ID=dev;Password=dev;MultipleActiveResultSets=True;ConnectRetryCount=3;");


    var db = new DapperTest(conn);
    var list = db.GetBuecher();

    Assert.AreEqual(2000, list.Count);
  }
}

Der Test hat eine Abhängigkeit zum Performance-Beispiel, entsprechend ist dieser für ein produktives Projekt kein gutes Vorbild. Wenn Du ihn verbessern willst, der Quellcode liegt hier.

In erster Linie ging es mir darum, zu überprüfen ob ein bestehendes .NET Framework-Paket von NuGet kompatibel mit dem .NET Standard 2.0 ist und in einer .NET Core 2.0 – Anwendung verwendet werden kann. Mit Dapper funktioniert das bereits sehr gut. Dadurch wird natürlich eine mögliche Portierung von Anwendungen hin zu .NET Core 2.0 weiter vereinfacht.

Wie sind Deine ersten Erfahrungen mit dem .NET Standard 2.0?