Um Abhängigkeiten und unerwünschte Seiteneffekte zu vermeiden setze ich bei meinen Repositories in aller Regel darauf diese nach außen hin abzugrenzen. Das bedeutet, dass ich beispielsweise auf IEnumerable<> verzichte und stattdessen immer List<> verwende.
Das hat zwar auch ein paar Nachteile (Kein Austausch der Implementierung im Vgl. zu IList<>, kein Lazy-Loading usw.) aber eben auch Vorteile - insbesondere den, dass alle Queries gegen die Datenbank ausgeführt werden, bevor die Daten die Repository-Methode verlassen. Somit kann ich den Datenzugriff hier exakt abgrenzen. Außerdem erwarte ich von jeder Methode null als Rückgabewert für den Fall, dass keine Daten in der Datenbank gefunden wurden.
Nun ist mir aber beim Testen meiner Repositories (später mehr ...) aufgefallen, dass Folgendes niemals null zurückliefert:
1: public List<Model.User> GetUsersByClientID(Guid clientID)
2: {
3: return Database.Users.Where(u => u.FKClientID == clientID)
4: .Select(u => Map(u)).ToList();
5: }
Im Zweifel ist das Ergebnis einfach eine leere Liste. Nicht besonders toll. Ich habe kurz recherchiert, aber keine wirklich elegante Lösung gefunden, da es für ToList() kein Gegenstück wie beispielsweise für Single() gibt - hier kann man mit SingleOrDefault() schlicht null zurückgeben lassen, wenn es keinen Treffer gibt.
Nun kann man in jeder Methode entsprechend auf einen Count von 0 prüfen und dann null zurückgeben - oder man packt es in eine Extension Method, die man dann genauso wie die vorhanden verwenden kann. Das dürfte zwar zum Lesen für Leute, die den Code nicht kennen, auf den ersten Blick schwieriger sein, aber hier überwiegen für mich die Vorteile ganz eindeutig.
1: public static class ToListOrDefaultExtension
2: {
3: public static List<TSource> ToListOrDefault(
4: this IQueryable<TSource> source)
5: {
6: return source.Count() > 0 ? source.ToList() : null;
7: }
8: }
Das Ergebnis:
1: public List<Model.User> GetUsersByClientID(Guid clientID)
2: {
3: return Database.Users.Where(u => u.FKClientID == clientID).Select(u => Map(u))
4: .ToListOrDefault();
5: }
That's it.
Update: Kommentare lesen ;-).