2012-10-19 11 views
9

Ich habe eine Tabelle mit einem folgenden Format.Casting String als DateTime in LINQ

PID  ID  Label  Value 
------------------------------------------ 
1  1  First Name Jenna 
1  2  DOB   10/12/1980 

ich alle PIDs abrufen müssen, wo Vorname mit J und Monat der DOB beginnend 10.

in meinem Code, ich abrufen diese in Datentabelle in C# und dann versucht, LINQ zu verwenden, die zum Abrufen Ergebnisse, die ich möchte. Dies ist nur ein Beispiel. Diese Labels können alles sein, was der Benutzer definiert.

mit LINQ Ich bin in der Lage, alle PIDs, wo Vorname mit J beginnen, abrufen, aber jedes Mal, wenn ich versuchte, Cast-Wert für DOB Ich bekomme Cast nicht gültig Fehler. Ich kann den Spaltentyp in der Datenbank nicht ändern, da Value beliebige Arten von Informationen enthalten kann.

Hier ist ein Stück meines Codes. Ich bin neu bei LINQ und versuche immer noch, darüber herauszufinden.

var resultQuery = from r in query.AsEnumerable() 
where (r.Field<string>("Label") == Label && 
r.Field<DateTime>("Value").Month == 10) 
select r.Field<int>("PID"); 
+0

Was ist der Datetime-Wert von "Jenna" ist? Ich bin mir nicht sicher, ob das machbar ist. – Bobson

Antwort

3

Da nicht alle Elemente in der Spalte Wert der Tabelle sind umwandelbar in DateTime, was Sie auf ungültige Conversions fehlschlagen haben. Sie können eine Klausel hinzufügen, die zuerst prüft, ob der Wert DateTime ist, und nur wenn dies der Fall ist, wird sie konvertiert und die Eigenschaft .Month überprüft.

DateTime d; 
var resultQuery = from r in query.AsEnumerable() 
        where (r.Field<string>("Label") == Label && 
         DateTime.TryParse(r.Field<string>("Value"), out d) && 
         d.Month == 10) 
        select r.Field<int>("PID"); 

Um möglicherweise die Lesbarkeit zu verbessern, können Sie auch diese extrahieren in eine separate Methode:

var resultQuery = from r in query.AsEnumerable() 
        let d = TryGetDate(r.Field<string>("Value")) 
        where (r.Field<string>("Label") == Label && 
         d != null && 
         d.Month == 10) 
        select r.Field<int>("PID"); 

private DateTime? TryGetDate(string value) 
{ 
    DateTime d; 
    return DateTime.TryParse(value, out d) ? d : default(DateTime?); 
} 
+2

Aus Gründen der Lesbarkeit und "Korrektheit", ich glaube, es wäre besser, die Datumslogik in eine separate Methode (DateTime? TryGetDate (String-Wert)) und Null, wenn nicht Parse-fähige ... – ioctlLR

+0

Vielen Dank beide . Wenn ich die Abfrage nur so ausführen würde, wie es goric vorgeschlagen hat, ist das kein Fehler, aber wenn ich versuche, resultquery in List zu konvertieren, schlägt es fehl. Wenn ich .Month == 10 nehme, funktioniert meine Liste gut. PID = resultQuery.ToList(); Wo PID ist definiert, um Art der Liste user1760153

+0

Nicht nur das, aber Ihr Code, wie es funktioniert nicht. Selbst wenn Sie die Zeichenfolge zu einem Datum analysieren können, können Sie sie nicht einfach auf ein Datum * umwandeln, was Sie hier tun. – Servy

2

Sie werden im Speicher, um am Ende das Filtern, die nicht sehr effizient ist.

So wählen Sie zunächst Ihre Daten

var data= from r in query.AsEnumerable(); 

auf die Daten filtern Dann

var filtered = from item in data 
       where item.Label == "Label" 
       && Convert.ToDateTime(item.DOB).Month == 10 
       select item.PID;