Je viens d'un terrain TSQL + C# et j'ai essayé de m'adapter à linq et EF. Les relations de plusieurs à plusieurs m'ont fait trébucher. J'ai des modèles avec plusieurs-à-plusieurs relations que je veux interroger à partir d'une base de données. Tels que:Entity Framework: Obtenir un modèle avec des modèles liés dans plusieurs à plusieurs relations
class Product{
public int ID {get;set;}
public string ProductName {get;set;}
public virtual ICollection<Tag> Tags {get;set;}
}
class Tag {
public int ID {get;set;}
public string TagName {get;set;}
public virtual ICollection<Product> Products {get;set;}
}
Je suis en mesure d'obtenir un produit lui-même de la DbContext, puis aller chercher plus tard, il est Tags associés comme ceci:
// product exists in memory as a Product with an empty product.Tags
var query = from p in db.Product
from t in db.Tags
where p.ID == product.ID
select p.Tags;
Ensuite, je peux attribuer les product.Tags avec les étiquettes récupérées. Évidemment, c'est très inefficace quand il s'agit de plusieurs produits si je dois interroger chaque produit. Avec linq et EF, je veux être en mesure d'obtenir un produit avec tous ses tags associés dans un aller-retour à la base de données. En outre, je veux pouvoir obtenir tous les produits et leurs étiquettes associées (ou une liste filtrée de produits). Comment le linq ressemblerait-il?
Edit:
Ok, après un peu plus bidouiller, j'ai ceci:
var query = db.Product.Include("Tags")
.Where(p => p.Tags.Any(t => t.Products.Select(m => m.ID).Contains(p.ID)));
C'est presque ce que je dois. Les résultats sont tous des produits avec des étiquettes. Manquant sont les produits qui n'ont pas de balises. Je pense à cela comme l'équivalent d'une jointure interne SQL. Je veux laisser l'extérieur joindre les étiquettes au produit, et renvoyer tous les produits avec des étiquettes facultatives. Comment obtenir tous les produits avec leurs tags associés sans exclure les produits sans tags?
Éditer:
C'était plus facile que je ne le pensais.
var query2 = db.Product.Include("Tags").DefaultIfEmpty();
Ceci permet d'obtenir tous les produits et leurs étiquettes respectives, y compris les produits sans étiquettes. Espérons que cela fonctionne pour les bonnes raisons ...