Consulta de asignación múltiple con Dapper

.net c# dapper sql sql-server

Pregunta

Tengo estas clases y sus tablas equivalentes en mi base de datos:

public class Entity
{
    public int Id { get; set; }
    public List<EntityIdentifier> Identifiers { get; set; }

    public BaseEntity()
    {
        Identifiers = new List<EntityIdentifier>();
    }
}

public class EntityIdentifier
{
    public int Id { get; set; }
    public int EntityId { get; set; }

    public string Code { get; set; }
    public string Value { get; set; }
}

Quiero consultar la base de datos con Dapper y automatizar los datos.

Tengo este ejemplo de mapeo múltiple, desde la página Dapper git :

var sql = 
@"select * from #Posts p 
left join #Users u on u.Id = p.OwnerId 
Order by p.Id";

var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});
var post = data.First();

post.Content.IsEqualTo("Sams Post1");
post.Id.IsEqualTo(1);
post.Owner.Name.IsEqualTo("Sam");
post.Owner.Id.IsEqualTo(99);

Sin embargo, en este ejemplo, cada niño (publicación) tiene un enlace a su padre (usuario). En mi caso, es el padre (entidad) quien apunta a una lista de niños (identificadores).

¿Cómo debo adaptar el código a mi caso?


Aquí está la consulta SQL que estoy usando:

SELECT e.*, i.*
FROM Entity e INNER JOIN EntityIdentifier i ON i.EntityId = e.Id

Respuesta aceptada

Este es un ejemplo que he encontrado en algún lugar de los sitios relacionados con Dapper. El punto aquí es tener un diccionario donde conserve Entity.ID como clave y Entity como valor del diccionario. Luego, en la expresión lambda, comprueba si el diccionario ya contiene la Entidad; si es así, simplemente agregue el EntityIdentifier a la lista Entidad, de lo contrario agregue la Entidad devuelta por Dapper al Diccionario

string cmdText = @"SELECT e.*, i.*
                   FROM Entity e INNER JOIN Identifier i ON i.EntityId = e.Id";
var lookup = new Dictionary<int, Entity>();
using (IDbConnection connection = OpenConnection())
{
    var multi = connection.Query<Entity, EntityIdentifier, Entity>(cmdText, 
                                (entity, identifier) =>
    {
        Entity current;
        if (!lookup.TryGetValue(entity.ID, out current))
        {
            lookup.Add(entity.ID, current = entity);
            current.Identifiers = new List<EntityIdentifier>();
        }
        current.Identifiers.Add(identifier);
        return current;
    }, splitOn: "i.ID").Distinct();
    return multi;
}

En algún momento esto se complica con el parámetro splitOn. No estoy seguro si necesita repetirlo agregando explícitamente a la instrucción Select (generalmente utilizo el patrón IDTable)



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué