2015-05-26 16 views
28

Come posso eseguire una query di relazione molti-a-molti utilizzando il codice Entity Framework prima e linq? Il problema è che EF crea automaticamente la tabella delle relazioni. Quindi, non ce l'ho nel mio contesto.Interroga una relazione molti-a-molti con linq/Entity Framework. CodeFirst

Questo è il modello relazionale:

enter image description here

ho bisogno di un elenco di articoli per un category_id specifica, in fondo replicare qualcosa di simile:

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

Tuttavia il mio DbContext hanno solo:

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

Grazie per qualsiasi Aiuto.

risposta

32

Si può fare questo:

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; 

In questo modo si otterrà gli articoli che soddisfa la condizione che si desidera. Questo è il codice SQL che viene generato da tale query:

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)) 
+0

Grazie much.It ha funzionato perfettamente. –

+1

Questo non è corretto, EF non è abbastanza intelligente da usare i join. Creerà invece una dichiarazione EXISTS. Le prestazioni possono essere un problema qui. – Talon

+0

@Talon, ora ho verificato quella query ed è vero che il provider di Linq EF 6.x sta generando un 'Exists' invece di un' join'. Grazie per il feedback. Sono d'accordo con te sulle prestazioni, ma se ometti la tabella di giunzione come parte del tuo modello, questo è l'unico modo per farlo. – octavioccl

5

Come su

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

Questo dovrebbe funzionare bene (produrre la giusta uniti dichiarazione di sql.)

+0

da dove viene la 'a'? Potresti chiarire cosa intendi per favore. –

+0

Dovrebbe essere 'c => c.Articles'. Questo si unirà a ciascun elenco di articoli delle categorie selezionate da Dove query. –

+0

Ottimo, questa è la soluzione giusta. EF generato INNER JOIN invece DOVE ESISTE. Con EXISTS è molto lento. –

1

Ho appena incontrato questo e ho pensato di pubblicare la soluzione che ho trovato per chiunque si imbattesse in questa pagina. Questo produce 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); 
0

Se si desidera solo l'intera tabella compresi tutti i rapporti, forse provare qualcosa di simile:

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

Esempio metodo LINQ sintassi

int category_ID = 1; 

var query = db.Articles 
    .Where(a => a.Categories 
    .Any(c => c.Category_ID == category_ID)) 
    .ToList(); 
Problemi correlati