Ich habe gerade von ActiveRecord / NHibernate zu Dapper gewechselt . Zuvor hatte ich alle meine Abfragen in meinen Controllern. Einige Eigenschaften, die auf meinen Modellen einfach zu implementieren waren (wie Zusammenfassungen / Summen / Summen / Durchschnittswerte), konnte ich jedoch durch Iteration über Instanzvariablen (Sammlungen) in meinem Modell berechnen.
Um genau zu sein, mein Project
hat eine Vorstellung von AppSessions
, und ich kann die Gesamtzahl der Sitzungen zuzüglich der durchschnittlichen Sitzungslänge berechnen, indem someProject.AppSessions
über someProject.AppSessions
iteriere.
Nun, da ich in Dapper bin, scheint das verwirrend zu sein: Meine Controller-Methoden machen jetzt Anfragen an die Datenbank via Dapper (was okay scheint), aber meine Model-Klasse macht auch Anfragen an die Datenbank über Dapper (was seltsam erscheint).
TLDR: Soll der DB-Zugriff in meinem Modell, Controller oder beidem erfolgen? Es scheint, dass beides nicht korrekt ist, und ich würde es gerne auf eine "Ebene" beschränken, so dass sich das spätere Ändern des DB-Zugriffsstils nicht zu sehr auswirkt.
Sie sollten ein Repository-Muster verwenden :
Bei Repositorys sind alle Datenbankabfragen in einem Repository gekapselt, das über die öffentliche Schnittstelle verfügbar gemacht wird, z.
public interface IGenericRepository<T> where T : class
{
T Get(object id);
IQueryable<T> GetAll();
void Insert(T entity);
void Delete(T entity);
void Save(T entity);
}
Dann können Sie injizieren ein Repository in einen Controller:
public class MyController
{
private readonly IGenericRepository<Foo> _fooRepository;
public MyController(IGenericRepository<Foo> fooRepository)
{
_fooRepository = fooRepository;
}
}
Dies hält die Benutzeroberfläche frei von DB-Abhängigkeiten und erleichtert das Testen. Aus Unit-Tests können Sie jeden Mock, der IRepository implementiert, injizieren. Dies ermöglicht dem Repository auch die Implementierung und den Wechsel zwischen Technologien wie Dapper oder Entity Framework ohne jegliche Client-Änderungen und zu jeder Zeit.
Das obige Beispiel verwendet ein generisches Repository, aber Sie müssen nicht; Sie können für jedes Repository, z. B. IFooRepository, eine separate Schnittstelle erstellen.
Es gibt viele Beispiele und viele Variationen davon, wie das Repository-Muster implementiert werden kann, also googlen Sie etwas mehr, um es zu verstehen. Hier ist einer meiner Lieblingsartikel. geschichtete Architekturen .
Noch ein Hinweis: Bei kleinen Projekten sollte es OK sein, Abfragen direkt in Controller zu stellen ...
Ich stimme @ void-ray bezüglich des Repository-Modells zu. Wenn Sie jedoch nicht in Schnittstellen und die Abhängigkeitsinjektion einsteigen möchten, können Sie Ihre Datenzugriffsebene dennoch trennen und statische Methoden verwenden, um Daten von Dapper zurückzugeben.
Wenn ich Dapper verwende, habe ich normalerweise eine Repository-Bibliothek, die sehr kleine Objekte oder Listen zurückgibt, die dann in ein ViewModel gemappt und an die View übergeben werden können (das Mapping wird von StructureMap erledigt, kann aber im Controller oder einem anderen Helfer gehandhabt werden) .