¿Cómo selecciono un objeto agregado de manera eficiente usando Dapper?

c# dapper sql

Pregunta

Digamos que tengo una serie de objetos que forman un agregado.

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;}
}

usando Dapper, ¿cuál es la mejor manera de llenarlos de tablas en una base de datos (en mi caso es postgres pero eso no debería importar). Las tablas en el ejemplo son prácticamente una a una con el modelo de objetos. La propiedad Items en la clase que representa relaciones de clave foránea con cada objeto subordinado. es decir, 3 tablas, A tiene una relación de Uno a Muchos con B, B tiene una relación de Uno a Muchos con C.

Entonces, para una identificación de IA dada, quiero que mis objetos también tengan todos sus datos secundarios.

Mi mejor suposición es que debería usar QueryMultiple de alguna manera, pero no estoy seguro de cuál es la mejor manera de hacerlo.

Respuesta aceptada

Creo que el asistente que propongo aquí: Multi-Mapper para crear jerarquía de objetos puede ser de ayuda.

var mapped = cnn.QueryMultiple(sql)
   .Map<A,B,A>
    (
       A => A.ID, 
       B => B.AID,
       a, bees => { A.Items = bees};  
    );

Suponiendo que extiende su GridReader y con un asignador:

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;
}

Puede extender este patrón para trabajar con una jerarquía de 3 niveles.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow