Tipps und Tricks rund um .NET und Visual Studio

„InnerException“-Ausgabe ohne Stacktrace
Keine Kommentare

Dr. Holger Schwichtenberg (MVP) teilt in der Kolumne „.NETversum“ sein Expertenwissen rund um .NET-Tools und WPF mit. In dieser Ausgabe geht es um die „InnerException“-Ausgabe ohne Stacktrace.

Bei der Ausgabe eines Exception-Objekts bekommt man viele Informationen über die Fehlerklasse und auch die inneren Fehler (InnerException): Klassenname, Fehlertext (Message) und Stacktrace. Das ist aber manchmal etwas zu viel des Guten, denn der Stacktrace kann sehr lang sein.

Die folgende Erweiterungsmethode für die Klasse System.Exception gibt im Standard nur die Fehlerklasse und den Fehlertext aus (Listing 1). Mit dem Parameter verbose kann man das Stacktrace optional mit ausgeben. Zudem kann man die verbose-Einstellung global setzen und im Aufruf der Methode diese Einstellung wieder außer Kraft setzen.

/// <summary>
///  Erweiterungen der Klasse Exception
/// </summary>
public static class ExceptionExtensions
{
  public static bool Verbose = false;

/// <summary>
/// Liefert Nachricht der Exception inkl. InnerException, aber optional ohne StackTrace!
/// </summary>
/// <param name="ex">Fehlerklasse</param>
/// <param name="verbose">Steuert, ob StackTrace ausgegeben wird</param>
/// <param name="forceNotVerbose">Übersteuert die globale Verbose-Einstellung</param>
/// <returns></returns>
public static string GetFullMessage(this Exception ex, bool verbose = false, bool forceNotVerbose = false, string separator = "\n")
{
  string ausgabe = ex.GetType().FullName + ": " + ex.Message + separator;
  if (ex.InnerException != null) ausgabe += GetFullMessage(ex.InnerException);
  if ((Verbose || verbose) && !forceNotVerbose) ausgabe += separator + ex.StackTrace;
  return ausgabe;
}
}

Listing 2 zeigt ein Anwendungsbeispiel, das GetFullMessage() im Vergleich zu ToString() zeigt.

private static void Demo_ExceptionAusgabe()
{
  try
  {
    MacheEinenFehler();
  }
  catch (Exception ex2)
  {
    CUI.Print("ToString()", ConsoleColor.Yellow);
    Console.WriteLine(ex2.ToString());
    CUI.Print("GetFullMessage()", ConsoleColor.Yellow);
    Console.WriteLine(ex2.GetFullMessage());
  }
}

private static void MacheEinenFehler()
{
  var ex1 = new ApplicationException("Berechnung nicht möglich",
    new InvalidOperationException("Ungültige Eingabedaten", new ArgumentNullException("Eingabewert")));
  throw ex1;
}

Abbildung 1 zeigt die Ausgabe des Beispiels.

Abb. 1: Ergebnisdarstellung

Abb. 1: Ergebnisdarstellung

UPDATE und DELETE per Lambdaausdruck

Massenoperationen kann man in der Grundausstattung des Entity Frameworks nicht in der LINQ- oder Lamdbasyntax absetzen, sondern nur per SQL:

ctx.Database.ExecuteSqlCommand("Delete Betrieb.Flug where FlugNr > {0}", grenze);

Wer lieber keine SQL-Befehle mehr schreiben will, weil der Code durch die möglichen Tippfehler fehleranfälliger wird, dem bietet das Projekt EntityFramework.Extended hier Hilfe an. Das Paket EntityFramework.Extended4 realisiert Erweiterungsmethoden mit Namen Update() und Delete(). Um diese zu aktivieren, ist ein using EntityFramework.Extensions; notwendig. Hier ist zu beachten, dass es Extensions nach dem Punkt heißen muss, nicht Extended wie im Paketnamen.

 

API Conference 2018

API Management – was braucht man um erfolgreich zu sein?

mit Andre Karalus und Carsten Sensler (ArtOfArc)

Web APIs mit Node.js entwickeln

mit Sebastian Springer (MaibornWolff GmbH)

Die Erweiterungsmethode Delete() kann man auf einer Klasse DbSet unter Angabe eines Lambdaausdrucks anwenden. Das folgende Listing zeigt zwei syntaktische Varianten dafür:

using (var ctx = new WWWings6Entities())
{
  var grenze = 20000;
  var anz1 = ctx.Flug.Delete(x=>x.FlugNr>grenze);
}
using (var ctx = new WWWings6Entities())
{
  var grenze = 20000;
  var q = ctx.Flug.Where(x => x.FlugNr > grenze);
  var anz3 = q.Delete();
}

Alternativ kann man Delete() auch auf einem IQueryable anwenden:

using (var ctx = new WWWings6Entities())
{
  var grenze = 20000;
  var q = ctx.Flug.Where(x => x.FlugNr > grenze);
  var anz3 = q.Delete();
}

Bei der Erweiterungsmethode Update() sind zwei Lambdaausdrücke anzugeben: einer für die Selektion, der andere für die Aktualisierung (Listing 3). Die zu aktualisierenden Werte legt man dabei in einem partiell befüllten Objekt fest. Hinsichtlich der Where-Klausel gibt es die gleichen Varianten wie bei Delete().

using (var ctx = new WWWings6Entities())
{
  var grenze = 20000;
  var anz1 = ctx.Flug.Update(x => x.FlugNr > grenze,
                             y => new Flug { FreiePlaetze = (short)(y.FreiePlaetze.Value-1) , NichtRaucherFlug = true });
}
using (var ctx = new WWWings6Entities())
{
  var grenze = 20000;
  var anz2 = ctx.Flug.Where(x => x.FlugNr > grenze)
                     .Update(y => new Flug { FreiePlaetze = (short)(y.FreiePlaetze.Value - 1) , NichtRaucherFlug = true });
}
using (var ctx = new WWWings6Entities())
{
  var grenze = 20000;
  var q = ctx.Flug.Where(x => x.FlugNr > grenze);
  var anz3 = q.Update(y => new Flug { FreiePlaetze = (short)(y.FreiePlaetze.Value - 1) , NichtRaucherFlug = true });
}

Aber Achtung: Die von EntityFramework.Extended erzeugten SQL-Befehle sind leider suboptimal. Sie arbeiten immer mit einem geschachtelten SELECT, obwohl dies gar nicht notwendig wäre. Aus der Sicht der Autoren von EntityFramework.Extended war dies aber die einfachste Implementierung, weil man einfach auf die vorhandene SELECT-Befehl-Generierung von Entity Framework aufsetzen kann. Die meisten Datenbankmanagementsysteme werden die Befehle dennoch performant ausführen, da sie selbst hier die unnötige Schachtelung wegoptimieren. Prüfen Sie aber bei Performanzproblemen unbedingt, ob ein selbstgeschriebener SQL-Befehl nicht schneller läuft!

Buchempfehlungdotnet_praxis

In den vergangenen Jahren haben Dr. Holger Schwichtenberg und Manfred Steyer im „Windows Developer“ regelmäßig Tipps und Tricks aus ihrem Alltag als Softwareentwickler, Berater und Trainer für .NET- und webbasierte Anwendungen veröffentlicht. Das vorliegende Buch ist eine aktualisierte und deutlich erweiterte Zusammenfassung dieser Tipps und Tricks. Es umfasst sowohl das .NET Framework und seine zahlreichen Teilbibliotheken als auch die beliebte JavaScript-Bibliothek AngularJS sowie die Entwicklungsumgebung Visual Studio und ergänzende Werkzeuge.

Mehr Infos: www.entwickler-press.de/Dotnet-Praxis

 

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

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -