Ähnliche LINQ Abfragen durch IQueryable kapseln

Wer öfters ähnliche LINQ Abfrage durchführen muss und sich dabei an das Clean Code Prinzip Don’t Repeat Yourself (DRY) halten will, der kann dies über das Interface IQueryable machen. Um das zu verdeutlichen, soll folgendes Beispiel dienen:

Stellen wir uns vor, wir haben einer Klasse mit 2 Datenbank-Abfragen, die zum Teil die gleichen Einschränkungen haben:

  • gemeinsame Anforderung: Hole alle Artikel aus dem Artikelstamm, die nicht auf gelöscht gesetzt sind und deren Erstelldatum innerhalb der letzten 12 Monate liegt
  • Abfrage 1: filtere zusätzlich auf die Einheit ‘Stück’
  • Abfrage 2: filtere alle, die als Lagerartikel markiert sind

Natürlich könnte man jetzt 2 gänzlich separate Abfragen machen. Das Problem ist, dass wenn man die 12 Monate auf 24 Monate ausdehnen will, dies an zwei Stellen erledigen muss. Das riecht (bad smells).

Eine Lösung wäre nun, dass ihr eine dritte Methode definiert, die ungefähr so aussehen könnte:

   1: Private Function GetStockArticles(ByRef vContext As cwDB.comWorkEntities) As IQueryable(Of cwDB.Article)

   2:     If vContext Is Nothing Then

   3:         Throw New ApplicationException("Kein Zugriff auf die Datenbank. DataContext war leer.")

   4:     Else

   5:         Dim lArticles As IQueryable(Of cwDB.Article) = _

   6:                     From X In vContext.Articles

   7:                      Where _

   8:                          X.IsStockArticle = True AndAlso _

   9:                          X.IsDeleted = False

  10:                      Select X

  11:  

  12:         If lArticles Is Nothing OrElse lArticles.Count < 1 Then

  13:             Throw New ApplicationException("Keine Lagerartikel gefunden")

  14:         End If

  15:  

  16:         Return lArticles

  17:     End If

  18: End Function

 

Das Ergebnis könnt ihr in den zwei Abfragen dann weiterverwenden. Zwei Anmerkungen dazu:

  • Ihr müsst den Context an die Methode übergeben, sonst könnt ihr später nicht auf das Ergebnis zugreifen.
  • Wenn ihr eine Liste zurückgeben würdet, hättet ihr den Nachteil, dass die Abfrage bereits durchgeführt wurde, sprich ihr hättet schon einen Datenbankzugriff gemacht. Durch IQueryable erhaltet ihr lediglich den ExpressionTree zurück, auf dem ihr die Abfrage verfeinern und dann feuern könnt.

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: