Impossible d'utiliser le multi-mapping dans Dapper

c# dapper multi-mapping

Question

En jouant avec Dapper, je suis assez content des résultats obtenus jusqu'à présent - intriguant!

Mais maintenant, mon prochain scénario serait de lire les données de deux tables: une table d’ Student et une table d’ Address .

Student table de l' Student a une clé primaire de StudentID (INT IDENTITY) , l' Address a un AddressID (INT IDENTITY) . Student également un FK appelé AddressID liant dans la table Address .

Mon idée était de créer deux classes, une pour chaque table, avec les propriétés qui m'intéressaient. De plus, j'ai placé une propriété PrimaryAddress de type Address sur ma classe Student en C #.

J'ai ensuite essayé de récupérer les données des étudiants et des adresses en une seule requête - je simule l'exemple donné sur la page Github :

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

Ici, un Post et un User sont récupérés, et le propriétaire du message est défini sur l'utilisateur - le type renvoyé est un Post - correct?

Donc, dans mon code, je définis deux paramètres pour la méthode d’extension générique Query : un Student en premier qui doit être renvoyé et une Address tant que seconde, qui sera stockée dans l’instance de l’étudiant:

var student = _conn.Query<Student, Address>
                  ("SELECT s.*, a.* FROM dbo.Student s 
                        INNER JOIN dbo.Address a ON s.AddressID = a.AddressID 
                        WHERE s.StudentenID = @Id", 
                    (stu, adr) => { stu.PrimaryAddress = adr; },  
                    new { Id = 4711 });

Le problème est - je reçois une erreur dans Visual Studio:

L'utilisation de la méthode générique 'Dapper.SqlMapper.Query (System.Data.IDbConnection, string, System.Func, dynamic, System.Data.IDbTransaction, bool, string, int ?, System.Data.CommandType?)' Nécessite 6 arguments de type

Je ne comprends pas vraiment pourquoi Dapper insiste pour utiliser cette surcharge avec 6 arguments de type ...

Réponse acceptée

Ce serait parce que j'ai changé les API et oublié de mettre à jour la documentation, j'ai corrigé l'erreur.

Veillez à consulter Tests.cs pour une spécification complète à jour.

En particulier, l'ancienne API utilisée pour effectuer une Action<T,U> pour effectuer le mappage, le problème était qu'elle semblait à la fois arbitraire et inflexible. Vous ne pouviez pas contrôler complètement le type de retour. Les nouvelles API prennent un Func<T,U,V> . Vous pouvez donc contrôler le type que vous recevez du mappeur et il n'est pas nécessaire qu'il soit mappé.

Je viens de créer une certaine flexibilité en ce qui concerne le multi-mapping, ce test devrait clarifier:

class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
}

class Address
{
    public int AddressId { get; set; }
    public string Name { get; set; }
    public int PersonId { get; set; }
}

class Extra
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public void TestFlexibleMultiMapping()
{
    var sql = 
@"select 
1 as PersonId, 'bob' as Name, 
2 as AddressId, 'abc street' as Name, 1 as PersonId,
3 as Id, 'fred' as Name
";
    var personWithAddress = connection.Query<Person, Address, Extra, Tuple<Person, Address,Extra>>
        (sql, (p,a,e) => Tuple.Create(p, a, e), splitOn: "AddressId,Id").First();

    personWithAddress.Item1.PersonId.IsEqualTo(1);
    personWithAddress.Item1.Name.IsEqualTo("bob");
    personWithAddress.Item2.AddressId.IsEqualTo(2);
    personWithAddress.Item2.Name.IsEqualTo("abc street");
    personWithAddress.Item2.PersonId.IsEqualTo(1);
    personWithAddress.Item3.Id.IsEqualTo(3);
    personWithAddress.Item3.Name.IsEqualTo("fred");

}

Dapper achemine toutes les API de multi-cartographie par une seule méthode, donc si quelque chose échoue, elle se retrouvera dans la configuration à 6 paramètres. L'autre élément du casse-tête était que je ne permettais pas de séparations super flexibles, que je viens d'ajouter.

Notez que le splitOn sera splitOn par défaut sur Id , ce qui signifie qu'il faudra une colonne appelée id ou Id comme première limite d'objet. Cependant, si vous avez besoin de limites sur plusieurs clés primaires qui ont des noms différents, par exemple un multi-mappage "à 3 voies", vous pouvez maintenant passer une liste séparée par des virgules.

Donc, si nous devions corriger ce qui précède, les éléments suivants fonctionneraient probablement:

 var student = _conn.Query<Student,Address,Student>
              ("SELECT s.*, a.* FROM dbo.Student s 
                    INNER JOIN dbo.Address a ON s.AddressID = a.AddressID 
                    WHERE s.StudentenID = @Id", 
                (stu, adr) => { stu.PrimaryAddress = adr; return stu;},  
                new { Id = 4711 }, splitOn: "AddressID").FirstOrDefault();



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