15 Stimmen

linq where-Klausel und Zählung führen zu einer Null-Ausnahme

Der nachstehende Code funktioniert, es sei denn, p.School.SchoolName stellt sich als Null heraus; in diesem Fall kommt es zu einer NullReferenceException.

if (ExistingUsers.Where(p => p.StudentID == item.StaffID &&
                        p.School.SchoolName == item.SchoolID).Count() > 0)
{
    // Do stuff.
}

ExistingUsers ist eine Liste von Benutzern:

public List<User> ExistingUsers;

Hier ist der relevante Teil des Stacktrace:

System.NullReferenceException: Objektreferenz nicht auf eine Instanz eines Objekts gesetzt.

bei System.Linq.Enumerable.WhereListIterator 1.MoveNext() at System.Linq.Enumerable.Count[TSource](IEnumerable 1 Quelle)

Wie sollte ich diese Where-Klausel behandeln?

Herzlichen Dank im Voraus.

29voto

Ahmad Mageed Punkte 91261

Ich vermute p.School null ist, nicht SchoolName . Fügen Sie einfach eine Nullprüfung vor dem Zugriff auf SchoolName . Verwenden Sie außerdem Any() um zu prüfen, ob es irgendwelche Ergebnisse gibt, anstatt Count() > 0 es sei denn, Sie brauchen die Zählung wirklich. Dies führt zu einer besseren Leistung, da nicht alle Elemente iteriert werden, wenn es welche gibt.

var result = ExistingUsers.Where(p => p.StudentID == item.StaffID
                            && p.School != null
                            && p.School.SchoolName == item.SchoolID)
                         .Any();

if (result) { /* do something */ }

1voto

Hydtechie Punkte 11

Für alle nullbaren Datenbankspalten sollten wir entweder eine Nullprüfung hinzufügen oder einen einfachen Vergleich durchführen a == b anstelle von a.ToLower() == b.ToLower() oder ähnliche String-Operationen.
Meine Beobachtung ist die folgende:
Wie Sie durch Enumerable von LINQ Query für Vergleich gegen mit Eingabe-String/Wert durchlaufen bekommen, würde jeder Null-Wert (der Datenbankspalte) und Operationen auf es Ausnahme auslösen, aber Enumerable wird NULL, obwohl Abfrage nicht null ist.

0voto

Garcia Julien Punkte 726

In dem Fall, in dem Sie den Nullwert erhalten möchten (alle Schüler, mit oder ohne Schule), verwenden Sie left join.

Es gibt ein gutes Beispiel auf MSDN

0voto

Bevan Punkte 42255

Wenn ich mich richtig erinnere (ich bin im Moment nicht an meinem Entwickler-PC und kann das nicht mit Reflector überprüfen), kann man mit der Option == Operator führt zum Aufruf des Instanz Umsetzung string.Equals(string) und nicht die statische Implementierung String.Equals(string, string) .

In der Annahme, dass Ihr Problem auf Folgendes zurückzuführen ist SchoolName Null ist, wie Sie vorschlagen, versuchen Sie dies:

if (ExistingUsers.Where(
    p => p.StudentID == item.StaffID 
    && String.Equals( p.School.SchoolName, item.SchoolID)).Count() > 0)
{
    // Do stuff.
}

Natürlich zählen auch die Kommentare der anderen Antworten:

  • Verwendung von Any() anstelle von Count() > 0 wird im Allgemeinen besser abschneiden
  • Si p.School die Null ist, brauchen Sie eine zusätzliche Prüfung

Ich hoffe, das hilft.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X