Bonjour à tous,
j'écris une application winform, et j'aimerais bien séparer la couche d'accès aux données, histoire que ça soit bien propre dès le départ.
J'utilise une base de donnée MySQL et n'utilise pas Linq (.Net 2.0 oblige)
je me suis donc penché sur le repository pattern.
Sur internet il y a plusieurs tutoriaux mais en général ils ne présentent que les cas simples où on veut récupérer toute la table.
Et donc dans leur cas, fastoche, toutes les classes Repository implémentent une interface générique IRepository<T> du genre:
ce que j'implémenterais comme ceci:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 public interface IRepository<T> { IList<T> SelectAll(); ... }
Ma question est: si je n'ai besoin de récupérer que certains utilisateurs suivant certains critères, quelle est la bonne manière de faire passer à une méthode l'expression permettant de filtrer ma requête sql?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 public class UserSQLRepository : IRepository<User> { #region membres publics public UserSQLRepository(IDbConnection dbConnection) { if (null == dbConnection) { throw new ArgumentNullException("dbConnection"); } m_dbConnection = dbConnection; } public List<User> SelectAll() { using (IDbCommand command = m_dbConnection.CreateCommand()) { // je remplis et retourne ma liste complète avec un "Select * From Users" } } #endregion #region membres privés private IDbConnection m_dbConnection; #endregion }
J'ai vu plusieurs solutions mais quelle est la meilleure?
solution 0.
faire une méthode SelectAll(string critères)
solution 1.
ne plus créer une interface générique mais faire une interface par classe repository avec chacune leurs méthodes de sélections en fonction de ce que je veux récupérer dans la table.
SelectByName(string[] names)
solution 2.
faire un truc du genre que j'ai vu sur le net:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 public interface IRepository<T> { IList<T> SelectAll(); IList<T> SelectAll(Func<T, bool> expression); } public class CustomersRepository : IRepository<Customer> { public IList<Customer> SelectAll() { return new List<Customer> { new Customer{ Id = 1, Name = "Customer1"}, new Customer{ Id = 2, Name = "Customer2"}, new Customer{ Id = 3, Name = "Customer3"}, new Customer{ Id = 4, Name = "Customer4"} }; } public IList<Customer> SelectAll(Func<Customer, bool> expression) { return new List<Customer> { new Customer{ Id = 1, Name = "Customer1"}, new Customer{ Id = 2, Name = "Customer2"}, new Customer{ Id = 3, Name = "Customer3"}, new Customer{ Id = 4, Name = "Customer4"} }.Where(expression).ToList(); } }
l'exemple utilise linq (Where) mais je peux l'adapter en utilisant un predicate.
Mais ce qui me chiffonne, c'est que si j'ai 20000 enregistrements, je devrais tous les charger de la base de donnée et les filtrer seulement dans la liste.
Qu'est ce qu'il faut faire pour que ça soit, maintenable, sûr et beau?
Partager