2016-08-27 2 views
0

Ich habe wirklich versucht mit diesem, aber kann es nicht ganz bekommen, um es zu arbeiten. Ich habe eine Reihe von Dateien, die ich verwende Linq zu analysieren, aber einige von ihnen haben ein Feld, das die anderen nicht haben. Es gibt keine Möglichkeit, über den Dateinamen zu wissen.scope mit einem Versuch fangen und linq

Hier ist der Code, der gegen die Datei ausgeführt wird:

var update = from d in document.Descendants("Update") 
         select new 
         { 
          OrderNumber = d.Element("OrderNumber").Value, 
          StopID = d.Element("StopID").Value, 
          TransmissionTime = d.Element("TransmissionTime").Value, 
          EventTime = d.Element("PODTime").Value, 
          recordCreated = d.Element("EventTime").Value, 
          EventType = d.Element("EventType").Value, 
          EventCode = d.Element("EventCode").Value, 
          POD = d.Element("POD").Value, 
          Note = d.Element("Note").Value, 
          CustomerID = d.Element("CustomerID").Value, 
          OrderID = d.Element("OrderID").Value, 
          StopRef = d.Element("StopRef").Value, 
          PieceCount = d.Element("PieceCount").Value, 
          TotalWeight = d.Element("TotalWeight").Value, 
          DriverID = d.Element("DriverID").Value 
         }; 

Nun das Problem ist, dass einige von ihnen nicht das Element haben („PODTime“), so ich brauche eine differnet Linq-Abfrage. Ich wollte nur versuchen/fangen und wenn es schief geht, laufe den anderen (Clodgy, den ich kenne). Aber natürlich sobald ich update in einen try/catch setze, kann ich nicht mehr darauf zugreifen.

Normalerweise würde ich es nur vor dem Versuch/Fang definieren - aber ich kann das hier nicht funktionieren.

Ich habe versucht:

System.Linq.Enumerable update = new System.Linq.Enumerable(); 

Aber das ist nicht richtig. Wenn mir jemand die richtige Richtung zeigen könnte, würde ich es begrüßen.

Lösung: Mit Vorschlaghämmern mit einem Let kombiniert Schubs:

var update = from d in document.Descendants("Update") 
          let elName = d.Element("PODTime") 
          select new 
          { 
           OrderNumber = d.Element("OrderNumber").Value, 
           StopID = d.Element("StopID").Value, 
           TransmissionTime = d.Element("TransmissionTime").Value, 
           EventTime = (elName != null) ? elName.Value : string.Empty, 
+0

Nun, Sie sind im Wesentlichen gehen Erstellen Sie zwei separate anonyme Objekte, wenn Sie zwei verschiedene Abfragen haben, wenn ein Feld nicht existiert. Warum nicht NULL oder eine leere Zeichenfolge auswählen, wenn das Feld nicht existiert? –

+0

müssen Sie Linq dafür verwenden? Die Deserialisierung wäre mit statischen Typen viel einfacher – rlee

+0

Collin - ich bin nicht sicher, wie man das macht, wenn ein Element nicht dort ist? Das würde wahrscheinlich das Problem für mich lösen. Ich bin noch nie auf dieses Bedürfnis gestoßen. –

Antwort

2

Sie haben die neue verwenden kann?. Betreiber dafür:

d.Element("CustomerID")?.Value 

Oder wenn Sie nicht die neueste C# verwenden können, können Sie eine „Safe“ Methode wickeln alle Ihre Anrufe in schreiben:

string SafeGetValue(XElement elem) 
{ 
    if (elem == null) 
    return null; 

    return elem.Value; 
} 
+0

Ich kann keine Informationen darüber finden, was? Betreiber tut oder wie man es benutzt. Wie heißt es, Google versagt mich! –

+0

@MostlyLucid Suche nach null bedingten Operatoren. Ich habe dir gezeigt, wie man es benutzt. Damit können Sie Ihre Anrufe verketten, ohne nach Nullen zu suchen. – SledgeHammer

+0

der Operator der Nullbedingung? ist eine neue Funktion in Visual Studio 2015 –

Verwandte Themen