Un constructeur par défaut sans paramètre est requis pour permettre une erreur de matérialisation lors de la lecture d'un objet avec une liste d'objets enfants.

asp.net-mvc-3 c# dapper

Question

J'ai ceci:

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

En utilisant Dapper, je récupère une liste d' object_a avec un nombre quelconque d'objets enfants 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;
    }

Lorsque j'appelle le code Dapper d'un contrôleur, j'obtiens cette erreur:

Un constructeur par défaut sans paramètre est requis pour permettre la matérialisation de Dapper

J'ai aussi essayé ceci:

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

                }, splitOn: "splitLimit");

Je pense que cela pourrait avoir quelque chose à voir avec IEnumerable<table_c> mais je ne comprends pas ce que je fais mal ici. J'ai lu des questions connexes que je suggère, mais je ne les comprends pas.

Je voudrais savoir ce que je fais mal et quel est le code correct. Merci!

Réponse acceptée

Le problème est le IEnumerable<> , ici:

Query<object_a, IEnumerable<table_c>, object_a>

Dapper ne peut pas créer un IEnumerable<table_c> , et il ne le fera jamais. Le fonctionnement de cette méthode est destiné à être:

Query<object_a, table_c, object_a>

ensuite, pour chaque ligne, dapper créera un object_a et un table_c partir de la ligne, puis utilisera votre méthode fournie par l'utilisateur pour combiner les deux. À l' heure actuelle, nous n'avons aucun code intégré pour effectuer une agrégation basée sur l' identité, mais qui pourrait être ajouté dans la méthode personnalisée - par exemple les essais de roll-up répété suivantes object_a instances:

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();



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi