2009-06-10 9 views
20

Hier ist die AbfrageLINQ to SQL und Null-Strings, wie verwende ich Contains?

from a in this._addresses 
where a.Street.Contains(street) || a.StreetAdditional.Contains(streetAdditional) 
select a).ToList<Address>() 

, wenn beide Eigenschaften in der where-Klausel haben Werte dies funktioniert gut, aber wenn beispielsweise a.StreetAdditional null ist (Die meisten der Zeit), werde ich eine null-Verweisausnahme erhalten .

Gibt es eine Arbeit um diese?

Danke,

+0

Hast du eine Ausnahme? Oder spekulieren Sie, als eine Ausnahme möglich ist? –

+0

Ich habe die Ausnahme. – Oakcool

+0

Wenn Sie eine 'NullReferenceException' dafür haben, führen Sie keine LINQ-SQL-Abfrage durch. –

Antwort

37

Die offensichtlichste:

from a in this._addresses 
where (a.Street != null && a.Street.Contains(street)) || (a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional)) 
select a).ToList<Address>() 

Alternativ können Sie eine Erweiterungsmethode schreiben für enthält, die ohne Fehler ein Null-Argument akzeptiert. Einige mögen sagen, dass es nicht so schön ist, solch eine Methode zu haben, weil sie wie ein normaler Methodenaufruf aussieht, aber für Nullwerte erlaubt ist (wodurch die normalen Nullprüfungs-Praktiken beiseite gelegt werden).

+0

Es sieht aus wie es funktioniert Danke – Oakcool

+4

Benutzerdefinierte Erweiterungsmethoden sind in LINQ to SQL nicht verwendbar. –

1

überprüfen, um sicherzustellen, dass die Eigenschaften nicht null sind

from a in this._addresses 
where (a.Street != null && a.Street.Contains(street)) || 
(a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional)) 
select a).ToList<Address>() 

Wenn die NULL-Prüfung falsch ist, dann wird die zweite Klausel nach dem & & wertet nicht.

1
from a in this._addresses 
where a.Street.Contains(street) || (a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional) 
select a).ToList<Address>() 
3

Sie müssen zunächst prüfen, ob StreetAdditionalnull ist.

Versuchen

where a.Street.Contains(street) || ((a != null) && a.StreetAdditional.Contains(streetAdditional)) 

Dies funktioniert, weil && ein Shortcut-Operator ist und wenn a != null falsch ergibt, wird der zweite Ausdruck mit dem null -Wertes nicht ausgewertet werden, da das Ergebnis false sowieso sein wird.

4

Ich würde eine Erweiterungsmethode erstellen, um eine leere Sequenz zurückzugeben, wenn null und dann Aufruf enthält Methode.

public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> pSeq) 
{ 
     return pSeq ?? Enumerable.Empty<T>(); 
} 

from a in this._addresses 
where a.Street.Contains(street) || 
     a.StreetAdditional.EmptyIfNull().Contains(streetAdditional) 
select a).ToList<Address>() 
+0

Sieht etwas komisch aus, weil ein 'null'-Objekt in der Lage ist, Elementfunktionen aufzurufen. – Dario

+0

Upvote für die Verwendung der ?? Operator. Das hätte ich auch vorgeschlagen. Wenn Sie der Ansicht sind, dass die Erweiterungsmethode die Abfrage merkwürdig aussehen lässt, können Sie auf die Erweiterungsmethode verzichten. –

42

ich den Null-Koaleszenz-Operator verwenden würde ...

(from a in this._addresses 
where (a.Street ?? "").Contains(street) || (a.StreetAdditional ?? "").Contains(streetAdditional) 
select a).ToList<Address>() 
+4

Dies ist ein sauberer Ansatz. Perfekt für den Umgang mit einem IQueryable DanKodi

2

Ich glaube nicht, SqlServer gibt Ihnen eine Null-Ausnahme. Wenn dies der Fall ist, wird dieser Code offensichtlich nicht über LinqToSql ausgeführt (da Sie die Frage markiert haben).

string.Contains würde in sql like übersetzt werden, die überhaupt keine Probleme mit Nullwerten hat.

1

Sie können überprüfen, ob die Variablen street und streetAdditional nicht null sind. Ich bin gerade über das gleiche Problem gestolpert und stellte sie auf eine leere Schnur, schien mein Problem zu lösen.

street = street ?? ""; 
streetAdditional = streetAdditional ?? ""; 
from a in this._addresses 
where a.Street.Contains(street) || a.StreetAdditional.Contains(streetAdditional) 
select a).ToList<Address>() 
-1

Eine Sache zu beachten ist, dass die Null zuerst ausgewertet werden sollte.

where (**a.Street != null** && a.Street.Contains(street)) || (a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional)) 
select a).ToList<Address> 

()