Dapper recibe List como parámetro de objeto de la consulta JOIN

c# dapper sql-server

Pregunta

Tengo problemas para usar Dapper cuando quiero asignar mi objeto de la base de datos.

class Set
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public List<Guid> GeneratorsList { get; set; }
}

Contiene una lista, así que he creado una tabla separada que lo contiene, así

CREATE TABLE [dbo].[Sets] (
    [Id]          UNIQUEIDENTIFIER NOT NULL,
    [Name]        VARCHAR (60)     NOT NULL,
    [Description] VARCHAR (60)     NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);

CREATE TABLE [dbo].[Set_Generator] (
    [SetId]       UNIQUEIDENTIFIER NOT NULL,
    [GeneratorId] UNIQUEIDENTIFIER NOT NULL,
    PRIMARY KEY CLUSTERED ([SetId] ASC, [GeneratorId] ASC),
    FOREIGN KEY ([SetId]) REFERENCES [dbo].[Sets] ([Id]) ON DELETE CASCADE
);

Y de esas tablas quiero recuperar el objeto Set correcto con el mínimo esfuerzo de código. Intenté unirme a ellos y escribir el resultado en Set , pero sin éxito.

var result = conn.Query<Set>(@"SELECT [S].[Id], [S].[Name], [S].[Description], [SG].[GeneratorId] AS [GeneratorsList] FROM [Sets] AS [S] INNER JOIN [Set_Generator] AS [SG] ON [S].[Id] = [SG].[SetId];");

Soy consciente de que simplemente podría recuperar Set from table y luego agregar GeneratorsList desde una consulta separada, pero estoy buscando una mejor solución.

var sets = conn.Query<Set>(@"SELECT * FROM [Sets];");
foreach(var set in sets)
{
    var generators = conn.Query<Guid>(@"SELECT [GeneratorId] FROM [Set_Generator] WHERE [SetId]=@SetId", new { SetId = set.Id });
    set.GeneratorsList = generators.ToList();
}

¿Hay una solución que requiera solo una consulta?

Respuesta aceptada

Con la consulta que proporcionó, puede recibir:

internal class GeneratorSet
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public Guid GeneratorId { get; set; }
}

Y use linq GroupBy para construir el objeto Set (-s):

var generatorSets = conn.Query<GeneratorSet>(@"SELECT [S].[Id], [S].[Name], [S].[Description], [SG].[GeneratorId] AS [GeneratorsList] FROM [Sets] AS [S] INNER JOIN [Set_Generator] AS [SG] ON [S].[Id] = [SG].[SetId];");;

var res = generatorSets.GroupBy(gen => gen.Id, p => p, (key, g) => new Set()
      { Id = key, Generators = g.Select(g => g.GeneratorId)});


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é