Disons que j'ai une série d'objets qui forment un agrégat.
public class C{
public string Details {get;set;}
}
public class B{
public string Details {get;set;}
public List<C> Items {get;set;}
}
public class A{
public long ID {get;set;}
public string Details {get;set;}
public List<B> Items {get;set;}
}
en utilisant Dapper, quelle est la meilleure façon de les remplir à partir de tables dans une base de données (dans mon cas, c'est postgres mais ça ne devrait pas avoir d'importance). Les tables de l'exemple sont pratiquement identiques à celles du modèle d'objet. La propriété Items sur la classe représentant les relations de clé étrangère avec chaque objet subordonné. c.-à-d. 3 tables, A a une relation un à plusieurs avec B, B a une relation un à plusieurs avec C.
Donc, pour un identifiant donné d’AI, mes objets doivent également avoir toutes leurs données enfants.
Ma meilleure supposition est que je devrais utiliser QueryMultiple en quelque sorte mais je ne suis pas sûr de la meilleure façon de le faire.
Je pense que l’aide que je propose ici: Multi-Mapper pour créer une hiérarchie d’objets peut être utile.
var mapped = cnn.QueryMultiple(sql)
.Map<A,B,A>
(
A => A.ID,
B => B.AID,
a, bees => { A.Items = bees};
);
En supposant que vous étendez votre GridReader et avec un mappeur:
public static IEnumerable<TFirst> Map<TFirst, TSecond, TKey>
(
this GridReader reader,
Func<TFirst, TKey> firstKey,
Func<TSecond, TKey> secondKey,
Action<TFirst, IEnumerable<TSecond>> addChildren
)
{
var first = reader.Read<TFirst>().ToList();
var childMap = reader
.Read<TSecond>()
.GroupBy(s => secondKey(s))
.ToDictionary(g => g.Key, g => g.AsEnumerable());
foreach (var item in first)
{
IEnumerable<TSecond> children;
if(childMap.TryGetValue(firstKey(item), out children))
{
addChildren(item,children);
}
}
return first;
}
Vous pouvez étendre ce modèle pour travailler avec une hiérarchie à 3 niveaux.