Remplir une relation un à plusieurs en utilisant Dapper ou via Linq

c# dapper linq one-to-many

Question

Entity - AllSalesTerritory contient List<MySalesPerson> représentant une à plusieurs relations. Je Sql requête pour récupérer les données où les deux entités sont mises en correspondance avec une colonne TerritoryId . J'utilise un code suivant pour remplir l'entité en utilisant Dapper micro ORM :

 List<AllSalesTerritory> allSalesTerrotories = _connection.Query<AllSalesTerritory, MySalesPerson, AllSalesTerritory>
                (query, (pd, pp) =>
                {
                    pd.SalesPersons.Add(pp);
                    return pd;
                }, splitOn: "BusinessEntityId")
                .ToList();

BusinessEntityId est la colonne de début de l'entité SalesPerson lors de l'exécution de l'instruction Sql

Le défi que je rencontre est que ce type de code aide à remplir facilement une relation List<MySalesPerson> , ici je ne reçois qu’une seule valeur dans chaque List<MySalesPerson> , au lieu d’agréger ces valeurs dans la collection, essentiellement le même résultat que la jointure SQL. question. Je peux facilement résoudre le problème en utilisant une simple boucle foreach et en agrégeant les valeurs pour MySalesPerson . Cependant, je veux comprendre:

  1. Est-ce que Dapper peut automatiquement m'aider à le réaliser, essayé quelques extensions, mais elles ne fonctionnaient pas comme prévu
  2. Un code Linq peut-il le faire pour moi, puisque c'est un peu l'inverse d'un SelectMany sur une entité avec une à plusieurs relations

Réponse acceptée

Vous pouvez utiliser un dictionnaire pour suivre les objets uniques AllSalesTerritory . En supposant que la propriété TerritoryId est un int cela fonctionnerait.

var territories = new Dictionary<int, AllSalesTerritory>()
_connection.Query<AllSalesTerritory, MySalesPerson, AllSalesTerritory>
    (query, (pd, pp) =>
    {
        AllSalesTerritory territory;
        if(!territories.TryGetValue(pd.TerritoryId, out territory))
        {
            territories.Add(pd.TerritoryId, territory = pd);
        }       

        territory.SalesPersons.Add(pp);
        return territory;
    }, splitOn: "BusinessEntityId");

List<AllSalesTerritory> allSalesTerrotories = territories.Values.ToList();

Fondamentalement, ce qui se passe ici est que Dapper retournera un AllSalesTerritory et un MySalesPerson pour chaque ligne dans les résultats de votre requête. Nous utilisons ensuite un dictionnaire pour voir si le AllSalesTerritory ( pd ) actuel a déjà été vu sur la base de TerritoryId . Si c'est le cas, la référence à cet objet est affectée à la variable de territory local. Si ce n'est pas le cas, nous assignons pd au territory et ajoutons cela au dictionnaire. Ensuite, nous ajoutons simplement le MySalesPerson actuel ( pp ) à la liste territory.SalesPersons .




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