2009-07-06 14 views
4

Ich habe eine ungerade linq Unterabfrage Problem.linq Unterabfrage zurückgeben null

die folgende Datenstruktur Gegeben:

Parents   Children 
-------   -------- 
Id     Id 
        ParentId 
        Location 
        HasFoo

(natürlich nicht die wirkliche Struktur ist, aber es ist nah genug für dieses Beispiel)

Ich bin in der Lage, diese Abfrage auszuführen und eine gewünschte bekommen Ergebnis:

bool b = (from p in Parents 
      from c in Children 
      where p.Id == 1 && c.ParentId == p.Id && c.Location == "Home" 
      select c.HasFoo).SingleOrDefault(); 

Also, wenn es ein Kind ist, dass die Lage „Home“ für einen Elternteil von Id 1 hat, werde ich dieses Kindes „HasFoo“ Wert erhalten, sonst, ich werde falsch bekommen, die ich S ist der "Standard" -Wert für ein Bool.

Allerdings, wenn ich versuche, und schreiben Sie die Abfrage, so habe ich eine Liste der übergeordneten Objekte, etwa so:

var parentList = from p in Parents 
       select new ParentObject 
       { 
        ParentId = p.ParentId, 
        HasHomeChildren = p.Children.Count(c => c.Location == "Home") > 0, 
        HasHomeChildrenWithFoo = (from c in p.Children where c.Location == "Home" select c.HasFoo).SingleOrDefault() 
       } 

ich folgende Fehlermeldung erhalten, wenn sie über die Liste iterieren:

The null value cannot be assigned to a member with type System.Boolean which is a non-nullable value type.

Ich sehe jedoch nicht, woher dieser "Null" -Wert kommt.

Antwort

2

Ich frage mich, ob der Compiler HasHomeChildrenWithFoo zu bool, aber dann Casting zu einem Nullable Bool (und damit Ihr SingleOrDefault Anruf) Casting bedeutet. Auf jeden Fall würde ich wetten, dass Sie es mit einem Cast auf einen NULL-fähigen Typ in diesem finalen Bereich korrigieren können, den Sie dann manuell auf "false" setzen können, wenn null. Es würde wahrscheinlich den Fehler verschwinden lassen, aber es ist ein Brute-Force-Kludon.

var parentList = from p in Parents 
       select new ParentObject 
       { 
        ParentId = p.ParentId, 
        HasHomeChildren = p.Children.Any(c => c.Location == "Home"), 
        HasHomeChildrenWithFoo = (from c in p.Children where c.Location == "Home" select (bool?)c.HasFoo) ?? false) 
       } 
+0

Scheint sehr seltsam, dies zu tun, aber es funktioniert! Vielen Dank! :) – Jonas

+1

Ja, ich weiß, es ist seltsam :). Froh, dass es funktioniert hat. Ich stolperte vor einiger Zeit über den Trick bei einer ähnlichen Frage (http://stackoverflow.com/questions/341264/). Der Artikel, den ich verlinkt habe, könnte mehr Licht ins Dunkel bringen, wenn Sie interessiert sind: http://www.interact-sw.co.uk/iangblog/2007/09/10/linq-aggregates –

+0

Toller Artikel ... Danke nochmal :) – Jonas