¿Cómo mapeo listas de objetos anidados con Dapper?

dapper orm

Pregunta

Actualmente estoy usando Entity Framework para mi acceso de db, pero quiero echarle un vistazo a Dapper. Tengo clases como esta:

public class Course{
   public string Title{get;set;}
   public IList<Location> Locations {get;set;}
   ...
}

public class Location{
   public string Name {get;set;}
   ...
}

Entonces, se puede enseñar un curso en varios lugares. Entity Framework hace el mapeo para que mi objeto Course se rellene con una lista de ubicaciones. ¿Cómo podría hacer esto con Dapper, incluso es posible o tengo que hacerlo en varios pasos de consulta?

Respuesta aceptada

Dapper no es un ORM completo, no maneja la generación mágica de consultas y demás.

Para su ejemplo particular, probablemente lo siguiente funcione:

Toma los cursos:

var courses = cnn.Query<Course>("select * from Courses where Category = 1 Order by CreationDate");

Agarra el mapeo relevante:

var mappings = cnn.Query<CourseLocation>(
   "select * from CourseLocations where CourseId in @Ids", 
    new {Ids = courses.Select(c => c.Id).Distinct()});

Agarra los lugares relevantes

var locations = cnn.Query<Location>(
   "select * from Locations where Id in @Ids",
   new {Ids = mappings.Select(m => m.LocationId).Distinct()}
);

Hacer un mapa de todo

Dejando esto al lector, usted crea algunos mapas e itera a través de sus cursos poblando con las ubicaciones.

Salvedad del in truco funcionará si tiene menos de 2.100 operaciones de búsqueda (SQL Server), si tiene más que probable que desee modificar la consulta para select * from CourseLocations where CourseId in (select Id from Courses ... ) si ese es el caso, también puede tirar todos los resultados de una vez con QueryMultiple


Respuesta popular

Alternativamente, puede usar una consulta con una búsqueda:

var lookup = new Dictionary<int, Course>();
conn.Query<Course, Location, Course>(@"
                SELECT c.*, l.*
                FROM Course c
                INNER JOIN Location l ON c.LocationId = l.Id                    
                ", (c, l) => {
                     Course course;
                     if (!lookup.TryGetValue(c.Id, out course)) {
                         lookup.Add(c.Id, course = c);
                     }
                     if (course.Locations == null) 
                         course.Locations = new List<Location>();
                     course.Locations.Add(l); /* Add locations to course */
                     return course;
                 }).AsQueryable();
var resultList = lookup.Values;

Mira aquí https://www.tritac.com/blog/dappernet-by-example/



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