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