Bonjour,
Je cherche à faire un supergénéric...
Du code parlant plus facilement, GO :
Code C# : 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 // Eléments de structure public abstract class Identifier { // Identifiant dans la base de données public int ID { get; set; } } public abstract partial class NNLinkHistory<TIdentifierA, TIdentifierB> : IHistory where IdentifierA : Identifier where IdentifierB : Identifier { // Identifiant de la première entité public int Identifier1ID { get; set; } // Lien de navigation vers la première entité public TIdentifierA Identifier1 { get; set; } // Identifiant de la seconde entité public int Identifier2ID { get; set; } // Lien de navigation vers la seconde entité Public TIdentifierB Identifier2 { get; set; } // Date d'association (Interface IHistory) public DateTime AssociationDate { get; set; } = DateTime.UtcNow; // Date de dissociation (Interface IHistory) public DateTime? DissociationDate { get; set; } } // Objets utiles public class Object1 : Identifier { // V1 public ICollection<O1O2H> Object2sV1 { get; set; } = new HashSet<O1O2H>(); // V2 public MyCollection<O1O2H> Object2sV2 { get; set; } = new MyCollection<O1O2H>(); } public class Object2 : Identifier { // V1 public ICollection<O1O2H> Object1sV1 { get; set; } = new HashSet<O1O2H>(); // V2 public MyCollection<O1O2H> Object1s { get; set; } = new MyCollection<O1O2H>(); } public class O1O2H : NNLinkHistory<Object1, Object2> { public int OtherProperty{ get; set; } }
Ceux qui utilise un ORM reconnaitront un lien 0,N---0,N entre 2 tables. D'ailleurs tant que j'y suis, je précise que j'utilise EFCore 3.1.17 et que je ne puis monter sur la version 5 car le framework utilisé est le standard 4.8 incompatible... no comment
A cela, j'ai ajouté une méthode d'extension pour aller chercher la relation active
Code C# : 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
31
32 public static TEntity GetActive<TEntity>(this ICollection<TEntity> histories, BaseDbContext ctx) where TEntity : class, IHistory { public NNLinkHistory<TIdentifierA, TIdentifierB> GetActive(DbContext ctx, bool isForceToReload = false) { // Si l'historique n'est pas null if (this.Count() > 0 || !isForceToReload) // Renvoyer l'historique return this.First(); // Récupérer la propriété à utiliser par son type var property = ctx.GetType() .GetProperties() .FirstOrDefault(o => o.PropertyType == typeof(DbSet<NNLinkHistory<TIdentifierA, TIdentifierB>>)); // Si la propriété n'a pas été trouvée if (property == null) // Générer une exception throw new InvalidCastException(); var queryable = (IQueryable<NNLinkHistory<TIdentifierA, TIdentifierB>>)property.GetValue(ctx); // Mettre à jour l'historique Clear(); if (query.Count() > 0) AddRange(query.ToList()); // Renvoyer l'historique return this.OrderByDescending(o => o.AssociationDate).FirstOrDefault(); }
Ca fonctionne impeccable mais j'aimerais pouvoir faire un objet à part entière pour pouvoir hériter de cet objet afin de définir une fonction GetActive légèrement différente pour une classe particulière :
Code C# : 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
31
32
33 public class MyCollection<TNNLinkHistory> : List<TNNLinkHistory> where TNNLinkHistory : NNLinkHistory<TIdentifierA, TIdentifierB> // Là déjà l'IDE râle car il ne connait pas TIdentifierA et TIdentifierB { public NNLinkHistory<TIdentifierA, TIdentifierB> GetActive(DbContext ctx, bool isForceToReload = false) { // Si l'historique n'est pas null if (this.Count() > 0 || !isForceToReload) // Renvoyer l'historique return this.First(); // Récupérer la propriété à utiliser par son type var property = ctx.GetType() .GetProperties() .FirstOrDefault(o => o.PropertyType == typeof(DbSet<NNLinkHistory<TIdentifierA, TIdentifierB>>)); // Si la propriété n'a pas été trouvée if (property == null) // Générer une exception throw new InvalidCastException(); var queryable = (IQueryable<NNLinkHistory<TIdentifierA, TIdentifierB>>)property.GetValue(ctx); // Mettre à jour l'historique Clear(); if (query.Count() > 0) AddRange(query.ToList()); // Renvoyer l'historique return this.OrderByDescending(o => o.AssociationDate).FirstOrDefault(); } }
Mais là ça coince
Bien évidemment, il n'y a pas que la fonction GetActive, il y a entre autre SetActive (qui s'appuie sur GetActive) mais seule celle-ci sera différente (d'où l'intérêt de l'héritage).
Auriez-vous une idée ?
Partager