131 votes

L'utilisation correcte de au mappage multiple dans Dapper

Je suis en train d'utiliser la au mappage multiple fonction de dapper pour retourner une liste de ProductItems et associés les Clients.

[Table("Product")]
public class ProductItem
{
    public decimal ProductID { get; set; }        
    public string ProductName { get; set; }
    public string AccountOpened { get; set; }
    public Customer Customer { get; set; }
} 

public class Customer
{
    public decimal CustomerId { get; set; }
    public string CustomerName { get; set; }
}

Ma dapper code est comme suit

var sql = @"select * from Product p 
            inner join Customer c on p.CustomerId = c.CustomerId 
            order by p.ProductName";

var data = con.Query<ProductItem, Customer, ProductItem>(
    sql,
    (productItem, customer) => {
        productItem.Customer = customer;
        return productItem;
    },
    splitOn: "CustomerId,CustomerName"
);

Cela fonctionne bien, mais il me semble avoir à ajouter de la colonne complète de la liste à la splitOn paramètre pour renvoyer tous les clients propriétés. Si je ne suis pas d'ajouter "Nomclient", elle renvoie null. Suis je manque de compréhension de la fonctionnalité de base de la au mappage multiple fonctionnalité. Je ne veux pas avoir à ajouter une liste complète des noms de colonne à chaque fois.

223voto

Sam Saffron Points 56236

J'ai juste couru un test qui fonctionne très bien:

var sql = "select cast(1 as decimal) ProductId, 'a' ProductName, 'x' AccountOpened, cast(1 as decimal) CustomerId, 'name' CustomerName";

var item = connection.Query<ProductItem, Customer, ProductItem>(sql,
    (p, c) => { p.Customer = c; return p; }, splitOn: "CustomerId").First();

item.Customer.CustomerId.IsEqualTo(1);

Le splitOn paramètre doit être spécifié en tant que point de split, la valeur par défaut de l'Id. S'il y a plusieurs points de scission, vous aurez besoin de les ajouter dans une liste délimitée par des virgules.

Dire que le jeu ressemble à ceci:

ProductID | ProductName | AccountOpened | Code Client | CustomerName 
--------------------------------------- -------------------------

Dapper a besoin de savoir comment diviser les colonnes de cet ordre dans les 2 objets. Un examen rapide montre que le Client commence à la colonne CustomerId, par conséquent splitOn: CustomerId.

Il y a une grosse mise en garde ici, si la colonne de la commande dans la table sous-jacente est renversé pour une raison:

ProductID | ProductName | AccountOpened | CustomerName | CustomerId 
--------------------------------------- -------------------------

splitOn: CustomerId entraînera une valeur null au nom du client.

Si vous spécifiez CustomerId,CustomerName comme points de scission, dapper suppose que vous essayez de diviser le jeu de résultats dans 3 objets. La première commence au début, le deuxième commence à CustomerId, le troisième à l' CustomerName.

4voto

Il y a une mise en garde. Si le champ code client est nul (typiquement dans les requêtes avec une jointure gauche) Dapper crée ProductItem avec le Client = null. Dans l'exemple ci-dessus:

var sql = "select cast(1 as decimal) ProductId, 'a' ProductName, 'x' AccountOpened, cast(null as decimal) CustomerId, 'n' CustomerName";
var item = connection.Query<ProductItem, Customer, ProductItem>(sql, (p, c) => { p.Customer = c; return p; }, splitOn: "CustomerId").First();
Debug.Assert(item.Customer == null); 

Et même une mise en garde/piège. Si vous n'avez pas la carte du champ spécifié dans splitOn et que le champ contient une valeur null Dapper crée et remplit l'objet connexe (Client, dans ce cas). Pour démontrer l'utilisation de cette classe avec la précédente de sql:

public class Customer
{
    //public decimal CustomerId { get; set; }
    public string CustomerName { get; set; }
}
...
Debug.Assert(item.Customer != null);
Debug.Assert(item.Customer.CustomerName == "n");  

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X