Tipps und Tricks rund um .NET und Visual Studio

Entity Framework Logging richtig nutzen
Kommentare

Dr. Holger Schwichtenberg (MVP) teilt in der Kolumne „.NETversum“ sein Expertenwissen rund um .NET-Tools und WPF mit. Dieses Mal zeigt er, wie man Entity Framework Logging richtig einsetzt.

Entity Framework ist dafür bekannt, dass es dem Softwareentwickler in vielen Situationen die Arbeit abnimmt, SQL-Befehle zu schreiben. Bei einigen Entwicklern ist Entity Framework genau dafür auch gefürchtet, denn sie verlieren die Kontrolle über das, was zur Datenbank geht. Die Protokollierung der ausgehenden SQL-Befehle ist also wichtig. Im Entity Framework war diese Funktionalität in den ersten Versionen leider sehr bescheiden vorhanden, denn der Entwickler konnte nur bei manchen, aber längst nicht allen Abfragen und gar nicht bei Einfüge-, Änderungs- und Löschoperationen an das erzeugte SQL herankommen.

Entity Framework Logging

Bei Verwendung der Basisklasse ObjectContext für die Kontextklasse muss der Entwickler für ein Abfrageobjekt eine Typumwandlung auf den Typ System.Data.Entity.Core.Objects.ObjectQuery durchführen, um Zugang zur Methode ToTraceString() zu erlangen, die den zu der Abfrage zugehörigen SQL-Befehl ausgibt:

 
var abfrage = from f in objctx.Flug where f.FlugNr < 4 select f;
string SQL = ((System.Data.Entity.Core.Objects.ObjectQuery)abfrage).ToTraceString();
Console.WriteLine("SQL für diese Abfrage: " + abfrage);

Einfacher geht es bei der Basisklasse DbContext, denn hier liefert ToString() für ein Abfrageobjekt den SQL-Befehl:

 1
var abfrage = from f in dbctx.Flug where f.FlugNr < 4 orderby f.Datum descending select f;
string SQL = (abfrage).ToString();
Console.WriteLine("SQL für diese Abfrage: " + abfrage);

Das hilft aber nicht weiter, sobald ein Operator im Spiel ist, der die Abfrage direkt ausführt, aber zugleich auch das SQL verändert, z. B. First(), FirstOrDefault(), Single(), SingleOrDefault() und Count().

Im nachstehenden Fall mit der Basisklasse DbContext landet auf dem Bildschirm nicht der SQL-Befehl, sondern der Klassenname des materialisierten Objekts:

var abfrage = (from f in ctx.Flug where f.FlugNr < 4 orderby f.Datum descending select f).FirstOrDefault();
string SQL = (abfrage).ToString();
Console.WriteLine("SQL für diese Abfrage: " + abfrage);

LINQ to SQL (der in .NET Framework 3.5 eingeführte ORM nur für Microsoft SQL Server, der inzwischen auf dem Abstellgleich steht) bietet eine allgemeine Möglichkeit der Überwachung. Die DataContext-Klasse von LINQ to SQL besitzt ein Attribut Log vom Typ System.IO.TextWriter. Daran kann man ein beliebiges TextWriter-Objekt zuweisen, z. B. Console.Out für die Konsolenausgabe oder System.IO.StreamWriter zum Schreiben in eine Textdatei.

Bei Entity Framework hat es bis zur Version 6.0 gedauert, bis Microsoft die Einsicht hatte, ein Logattribut in die Basisklasse DbContext im Unterobjekt Database einzubauen. Dieses Mal ist man bei der Implementierung noch offener und setzt nicht auf System.IO.TextWriter, sondern erwartet nur einen Delegate mit dem Typ Action<string>, also eine Methode mit der Signatur void Name(string). Dies kann Console.WriteLine() sein, aber eben auch eine beliebige eigene Methode, wie das nachstehende Listing zeigt. Die Methode InFarbeAnKonsoleAusgeben() wird ihrem Namen gerecht und gibt alle von Entity Framework Context empfangenen Zeichenketten im Konsolenfenster aus. Dabei macht sich die Methode zu Nutze, dass der Entity Framework Context einige Zeichenketten mit zwei Minuszeichen (entspricht einem Kommentar in SQL) einleitet.

class LoggingDemo
  {

    /// <summary>
    /// Protokollierung an die Konsole in verschiedenen Farben
    /// </summary>
    public static void InFarbeAnKonsoleAusgeben(string s)
    {
      var FarbeVorher = Console.ForegroundColor;
      if (s.StartsWith("--")) // Es sind Metadaten in Kommentarform
      {
        Console.ForegroundColor = ConsoleColor.Green;
      }
      else // Es ist ein SQL-Befehl
      {
        Console.ForegroundColor = ConsoleColor.Yellow;
      }
      Console.Write(s);
      Console.ForegroundColor = FarbeVorher;
    }

  public static void Run()
  {
    // Kontext erzeugen
    WWWings6Entities ctx = new WWWings6Entities();

    // Protokollierungsmethoden Action<string> setzen
    ctx.Database.Log = InFarbeAnKonsoleAusgeben;

    Console.WriteLine("============== Flüge laden und löschen");
    foreach (var f in ctx.Flug.Where(f => f.FlugNr < 4))
    {
      ctx.Flug.Remove(f);
      ctx.SaveChanges();
      Console.WriteLine("Flug #" + f.FlugNr + " gelöscht.");
    }

    Console.WriteLine("============== Flüge neu erzeugen");
    for (int i = 1; i <= 3; i++)
    {
      Flug f = new Flug();
      f.FlugNr = i;
      f.Abflugort = "Essen/Mülheim";
      f.Zielort = "München";
      f.FreiePlaetze = 10;
      f.Plaetze = 210;
      f.Datum = new DateTime(2011, 8, 1);
      ctx.Flug.Add(f);
      ctx.SaveChanges();
      Console.WriteLine("Flug #" + f.FlugNr + " erzeugt.");
    }

    Console.WriteLine("============== Flüge laden und ändern");
    foreach (var f in ctx.Flug.Where(f => f.FlugNr < 4))
    {
      f.FreiePlaetze--;
      ctx.SaveChanges();
      Console.WriteLine("Flug #" + f.FlugNr + " geändert.");
    }

  }
}

Abbildung 1 zeigt die Ausgabe. Die gesendeten SQL-Befehle sind nicht mit den Minuszeichen eingeleitet. Diese gibt die Methode InFarbeAnKonsoleAusgeben() in gelb aus. Nach den zwei Minuszeichen folgen Informationen über Parameter, Ausführungszeitpunkt, Ausführungsdauer und Ergebnismenge. Diese gibt die Methode InFarbeAnKonsoleAusgeben() in Grün aus.

Abb. 1: Ausgabe in farbiger Darstellung

Abb. 1: Ausgabe in farbiger Darstellung

Was und wie protokolliert wird, kann der Entwickler genauer über einen DatabaseLogFormatter oder einen IDbCommandInterceptor steuern.

Windows Developer

Windows DeveloperDieser Artikel ist im Windows Developer erschienen. Windows Developer informiert umfassend und herstellerneutral über neue Trends und Möglichkeiten der Software- und Systementwicklung rund um Microsoft-Technologien.

Natürlich können Sie den Windows Developer über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist der Windows Developer ferner im Abonnement oder als Einzelheft erhältlich.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -