web-dev-qa-db-fra.com

Interrogez une relation plusieurs-à-plusieurs avec linq/Entity Framework. Code d'abord

Comment interroger une relation plusieurs à plusieurs en utilisant d'abord le code Entity Framework et linq? Le problème est que EF crée automatiquement la table de relations. Donc, je ne l'ai pas dans mon contexte.

C'est le modèle relationnel:

enter image description here

J'ai besoin d'une liste d'articles pour un Category_Id spécifique, essentiellement, répliquer quelque chose comme ça:

select a.Id, a.Title,a.ShortDescription                       
from Articles a
join CategoryArticles ca on ca.Article_Id=a.Id
where ca.Category_Id  = @parameter

Cependant, mon dbcontext n'a que:

public DbSet<Article> Articles { get; set; }
public DbSet<Category> Categories { get; set; }.

Merci pour toute aide.

32
D.B

Tu peux le faire:

var cat_id=1; // Change this variable for your real cat_id

var query= from article in db.Articles
           where article.Categories.Any(c=>c.Category_ID==cat_id)
           select article;

De cette façon, vous obtiendrez les articles qui répondent à la condition souhaitée. C'est le code SQL généré par cette requête:

    SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Title] AS [Title]
    FROM [dbo].[Articles] AS [Extent1]
    WHERE  EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[ArticleCategories] AS [Extent2]
        WHERE ([Extent1].[Id] = [Extent2].[Article_Id]) AND ([Extent2].[Category_Id] = @p__linq__0))

Mettre à jour

Une autre option pourrait utiliser la méthode d'extension SelectMany (comme l'a souligné @Khaled) en démarrant votre requête à partir de Categories au lieu de Articles:

var query= db.Categories.Where(c=>c.Category_ID==cat_id).SelectMany(c=>Articles);

Cela générerait une jointure Inner au lieu de EXIST qui est le produit de la méthode d'extension Any.

37
octavioccl

Que diriez-vous

db.Categories.Where(c => c.Id == categoryId).SelectMany(c => c.Articles)?

Cela devrait fonctionner correctement (produire la déclaration SQL jointe à droite.) 

6
Khaled Rashad

Je viens juste de le voir et je me suis dit que je publierais la solution que j'ai trouvée pour tous ceux qui tombent sur cette page. Cela produit un INNER JOIN.

var category_id = 24;

var query = (from article in Articles
             from category in article.Categories.Where(x => x.Category_ID == category_id)
             select article);
2
JOpuckman

Exemple de syntaxe de méthode linq

int category_ID = 1;

var query = db.Articles
    .Where(a => a.Categories
    .Any(c => c.Category_ID == category_ID))
    .ToList();
2
Mauricio Ferraz

Si vous voulez juste la table entière, y compris toutes les relations, essayez peut-être quelque chose comme ceci:

List<CategoryArticle> rec = context.Category.SelectMany(a => a.Articles.Select(c => new CategoryArticle { Category_Id = c.Id, Article_Id = a.Id })).ToList();
1
juanora

Ajouter et interroger la table de jonction:

  var articles = (from ca in _context.CategoryArticles
                  inner join a in _context.Articles on a.Id equals ca.Article_Id
                  inner join c in _context.Catgories on c.Id equals ca.Category_Id
                  where ca.Category_Id equals catId
                  select c).ToList();
0
user10728126