Un-plusieurs sans exposer les collections enfants et / ou les clés étrangères dans le modèle

c# dapper orm

Question

J'ai un problème avec Dapper lorsque je n'expose pas mes clés étrangères et mes collections enfants dans le modèle POCO. Prenons un exemple simple avec les deux entités:

Bike (Id, ModelName)
Tire (Id, Tread)

Dans la base de données, chaque pneu possède une clé étrangère pour Bike. Mais mon modèle ne le fait pas. À partir de la base de données, je souhaite matérialiser cette structure dans un Dictionary<Bike, IEnumerable<Tire>> . Où chaque vélo (unique) aura deux pneus.

Je pourrais sélectionner cette relation un-à-plusieurs en utilisant la requête suivante:

SELECT b.Id, b.ModelName, t.Id, t.Tread
FROM Bike b
JOIN Tire t ON b.Id = t.bike_id

Pour cartographier cela en utilisant Dapper, j'ai fait ce qui suit:

var dbResult = connection.Query<Bike, Tire, KeyValuePair<Bike, Tire>>("sql-query-above",
(a, s) => new KeyValuePair<Bike, Tire>(a, s);
splitOn: "Id");

Et pour transformer ce résultat en mon dictionnaire, en utilisant LINQ:

Dictionary<Bike, IEnumerable<Tire>> dict = dbResult.GroupBy(g => g.Key, g => g.Value).ToDictionary(g => g.Key, g => g.AsEnumerable());

Et il renvoie correctement la structure de données:

Bike #1
 - Tire #1
 - Tire #2
Bike #2
 - Tire #3
 - Tire #4

Mais est-ce le moyen le plus efficace de matérialiser cette structure de données? Une alternative serait d'éviter le dictionnaire et de créer d'autres entités qui exposent les clés et les relations étrangères (par exemple, la collecte de pneus sur Bike et FK on Tire) et d'utiliser une approche de mappage telle que décrite ici . Mais je voudrais éviter cela dans mon modèle car cela donnerait beaucoup de cours supplémentaires. Mais qu'en est-il des performances? Est-ce pire ou pareil?

Réponse populaire

Je ne suis pas un expert dans l'utilisation de Dapper mais j'ai rencontré des limitations comme celle que vous rencontrez. J'ai eu une situation similaire où l'une des propriétés de mon objet était une collection comme vous les pneus. J'ai trouvé plus simple de créer une seconde requête pour remplir ces types de collections internes avec une méthode d'extension.

Donc, vous pouvez simplement saisir tous les vélos en premier et ensuite appeler votre méthode d'extension pour récupérer les données du pneu comme:

dict.WithTires();    

Je sais que c'est un deuxième appel à la base de données, mais le compromis est que vous pouvez toujours prendre un vélo sans avoir à obtenir les informations sur les pneus à chaque fois.

En outre, vous pouvez envisager d'ajouter la collection de pneus comme une propriété à votre classe de vélo dont IMHO est préférable à l'utilisation d'un dictionnaire. Si vous aviez quelque chose comme ça:

public class Bike
{
    public int id { get; set; }
    public string modelName { get; set; }
    public IList<Tires> tires { get; set; }
}

public class Tires
{
    public int id { get; set; }
    public string tread { get; set; }
}

Vous pouvez facilement créer une méthode d'extension pour saisir les données de pneus d'un vélo individuel ou d'une collection de vélos:

Bike myBike = new Bike();
List<Bike> bikeCollection = new List<Bike>();

myBike.WithTires();
bikeCollection.WithTires();



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