2016-07-26 24 views
2

Lets sagen, dass ich diesen Code haben:Kann ich beim Debuggen ein Objekt anzeigen, das in LINQ eine Ausnahme verursacht?

IDictionary<int, int> itemPriceDict = loadItemPriceDictionary(); 
IList<IRow> dbItems = loadItemsFromDatabase(); 

IList<ItemDTO> itemDTOs = dbItems 
    .Select(dbItem => new ItemDTO() 
    { 
     Id = dbItem.Id, 
     Label = dbItem.Label, 
     PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException 
    }) 
    .ToList(); 

und ich manchmal eine KeyNotFound Ausnahme erhalten, wenn gegebenen Preisschild für die gegebene dbItem nicht existiert.

Nun, wenn in Visual Studio Debuggen und eine Ausnahme ausgelöst wird, können Sie sehen, Stacktrace, Target, die Sie zeigen, welche Codezeile es ausgelöst, aber ist es möglich, um herauszufinden, welches Objekt (dbItem) die Ausnahme verursacht und seine Daten im Debugger anzeigen? Zum Beispiel im Watch-Fenster?

Ich möchte:

  1. Entweder wissen, welche Schlüssel im Wörterbuch
  2. Oder noch besser kennen

aber der Schlüssel und auch die dbItem verarbeitet in Select nicht vorlag ohne irgendeinen Code hinzufügen oder ändern zu müssen.

P.S .: Ich weiß, ich kann den Code als Zyklus neu schreiben, aber ich möchte nicht.

Antwort

0

Es stellt sich heraus, dass es völlig in Ordnung ist, eine solche Aufgabe zu inspizieren. Hier ist der Demo-Code in Aktion:

Inspecting variable in LINQ while exception is thrown

Darüber hinaus wird in Visual Studio 2015 ist es möglich, Lambda-Expression direkt in Watch Fenstern zur Ausgabe von Sammlungen abzufragen, bevor die Linie, die die Ausnahme auslöst.

enter image description here

0

hinzufügen Versuchen Sie eine andere statment:

IList<ItemDTO> itemDTOs = dbItems.Where(dbitem => dbitem.itemPriceDict[dbItem.Id] != null) 
    .Select(dbItem => new ItemDTO() 
    { 
     Id = dbItem.Id, 
     Label = dbItem.Label, 
     PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException 
    }) 
    .ToList(); 
+2

Dies würde nicht funktionieren. Sie würden KeyNotFoundException in der Where-Klausel erhalten, da das Wörterbuch nicht null zurückgibt, wenn der Schlüssel nicht vorhanden ist. –

+0

ok versuchen Sie es so: Wo (dbitem => dbitem.itemPriceDict [dbItem.Id] .Any()) – MKasprzyk

+0

Leider würden Sie KeyNotFound Ausnahme auch erhalten. Das geschieht bei dbitem.itemPriceDict [dbItem.Id] vor dem Aufruf von Any(). Du meinst das: Wo (dbItem => itemPriceDict.ContainsKey (dbItem.Id)) Aber ich möchte keinen Code ändern. Ich würde es in der Debugger-Ansicht sehen - Watch window zum Beispiel. –

4

Sie schreiben könnte Ihr Select als solche:

.Select(dbItem => 
    { 
     return new ItemDTO() 
     { 
      Id = dbItem.Id, 
      Label = dbItem.Label, 
      PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException 
     }) 
    } 
    .ToList(); 

Dass Sie Haltepunkte in den ausgewählten Auswertungen zu platzieren erlauben würde.

Besser noch, gehen Sie in das Debug-Menü, wählen Sie dann Ausnahmen (es ist unter dem Windows-Untermenü auf meiner Visual Studio Edition).

Dann richten Sie es so, dass es auf KeyNotFoundException oder eine beliebige Ausnahme Ihrer Wahl bricht.

Der Debugger wird dann automatisch erzeugt, wenn eine Ausnahme erlaubt auftritt Sie den Zustand der zugehörigen Objekte

2

für Debug-Zwecke prüfen Sie können dies tun:

IList<ItemDTO> itemDTOs = dbItems 
      .Select(dbItem => { 
       try 
       { 
        var value = itemPriceDict[dbItem.Id]; 
       } 
       catch (KeyNotFoundException) 
       {//Breakpoint goes here 
       } 
       // Possible KeyNotFoundException 
       new ItemDTO() 
       { 
        Id = dbItem.Id, 
        Label = dbItem.Label, 
        PriceTag = itemPriceDict[dbItem.Id] // Possible KeyNotFoundException 
       }; 
      }) 
      .ToList(); 

oder direkt die Liste zu bekommen, dies:

var missingKeys = dbitems.Where(dbItem => !itemPriceDict.ContainsKey(dbItem.Id)).ToList(); 
+0

Das funktioniert gut zu Debuggingzwecken. Aber Sie müssen den Code neu schreiben. Ich möchte das Objekt im Watch Window oder irgendwo untersuchen, ohne den vorhandenen Code ändern zu müssen. –

+0

Ihre Optionen sind sehr begrenzt, wenn Sie nicht Ihren Code ändern möchten ... Soweit ich sagen kann, wenn Sie möchten, dass Ihr Code unverändert bleibt, ist Ihre einzige Option, einen Haltepunkt innerhalb des LAMBA Ausdruck (der neuen ItemDTO-Teil), dann stoppen und überprüfen Sie jede ID im Wörterbuch manuell. Programmierung ist ein dynamischer Beruf, Sie müssen Ihren Code ändern, wenn Sie korrekte Ergebnisse erhalten möchten. – MichaelThePotato

+0

Natürlich müssen wir unseren Code während des Debuggens ändern. Ich war nur neugierig, ob ich das Objekt im Überwachungsfenster/sofortigen Fenster abfragen kann, das schneller ist, als Code zu modifizieren, neu aufzubauen und zu einer unterbrochenen Codezeile zu laufen. –

0

Wenn kein Schlüssel im Wörterbuch finden Sie eine KeyNotFoundException Ausnahme erhalten. Behalten Sie eine Top-Variable bei und weisen Sie den Schlüssel jedes Mal zu, wenn Sie die Linq-Abfrage einfügen. Sie können Ihren Code mit try and catch blockieren.

(KeyNotFoundException ex)

try 
    { 
     int key; 

     Dictionary<int, int> dict = new Dictionary<int, int>() 
     { 
      {1, 2}, 
      {2,3} 
     }; 

     var x = (from y in dict 
       select new 
       { 
        value = dict[4] 

       }).ToList(); 

    } 
    catch (KeyNotFoundException ex) 
    { 
     //key that is not there 
    } 
    catch (Exception ex) 
    { 

    } 
2

[Haftungsausschluss: Ich bei OzCode arbeiten]

Haben Sie OzCode versucht. Die Unterstützung für Linq-Debugging wurde zu EAP hinzugefügt und eine der Funktionen ist, dass es vorhersagen kann, ob eine Abfrage eine Ausnahme auslöst und das beanstandete Element anzeigt.

enter image description here

Auf diese Weise brauchen Sie nicht, Ihren Code oder zu versuchen und zu debuggen es in Ihrem Kopf sezieren.