Se requiere un constructor predeterminado sin parámetros para permitir el error de materialización de dapper cuando se lee un objeto con una lista de objetos secundarios

asp.net-mvc-3 c# dapper

Pregunta

Tengo esto:

public class object_a
{
    public int ta_Id { get; set; }
    public string ta_Label { get; set; }
    public IEnumerable<table_c> SomeName { get; set; }
}

public class table_b
{
    public int Id {get;set;}
    public int SomeId {get;set;}
    public int FK_A {get;set;}
}

public class table_c
{
    public int Id {get;set;}
    public int Max {get;set;}
    public string Label {get;set;}
    public int FK_A {get;set;}
}

Usando Dapper, recupero una lista de object_a con cualquier cantidad de objetos secundarios table_c

using (System.Data.SqlClient.SqlConnection sqlConnection = new System.Data.SqlClient.SqlConnection(_con))
{
        sqlConnection.Open();
        var sql = string.Format(
        @"
        select ta.Id as ta_Id, ta.Label as ta_label, splitLimit = '', tc.Id, tc.Max, tc.Label
        from table_a as ta
        left join table_b as tb
        on tb.FK_A = ta.Id
        left join table_c as tc
        on tc.FK_A = ta.Id
        where tb.SomeId = SomeInt);

        var items = sqlConnection.Query<object_a, IEnumerable<table_c>, object_a>(sql, (a, c) => { a.c = table_c; return a; }, splitOn: "splitLimit");
        return items;
    }

Cuando llamo al código Dapper desde un controlador obtengo este error:

Se requiere un constructor predeterminado sin parámetros para permitir la materialización dapper

También he intentado esto:

var items = sqlConnection.Query<object_a,IEnumerable<table_c>, object_a>(sql, (a, c) => 
{ 
                    if (c!= null) 
                    {
                        a.SomeName = c;
                    } 
                    return a; 

                }, splitOn: "splitLimit");

Creo que podría tener algo que ver con IEnumerable<table_c> pero no entiendo qué estoy haciendo mal aquí. He leído preguntas relacionadas que TES sugieren, pero no las "entiendo".

Me gustaría saber qué estoy haciendo mal y cuál es el código correcto. ¡Gracias!

Respuesta aceptada

El problema es IEnumerable<> , aquí:

Query<object_a, IEnumerable<table_c>, object_a>

IEnumerable<table_c> no puede crear un IEnumerable<table_c> , y nunca lo IEnumerable<table_c> . La forma en que funciona este método pretende ser:

Query<object_a, table_c, object_a>

luego, para cada fila, object_a creará un object_a y una table_c de la fila, luego usará el método proporcionado por el usuario para combinar los dos. Actualmente, no tenemos ningún código incorporado para realizar la agregación basada en la identidad, pero eso podría agregarse en el método personalizado; por ejemplo, los siguientes intentos para object_a instancias de object_a repetidas:

var identityMap = new Dictionary<int, object_a>();
var data = Query<object_a, table_c, object_a>(sql, (a, c) => {
    object_a master;
    if(!identityMap.TryGetValue(a.ta_id, out master)) {
        identityMap[a.ta_id] = master = a;
    }
    var list = (List<table_c>)master.SomeName;
    if(list == null) {
        master.SomeName = list = new List<table_c>();
    }
    list.Add(c);
    return master;
}, ...).Distinct().ToList();


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