Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Query a many-to-many relationship with linq/Entity Framework. CodeFirst

How can I query a many-to-many relationship using Entity Framework code first and linq? The problem is that EF create automatically the relation table. So, I don't have it in my context.

This is the relational model:

enter image description here

I need a list of Articles for a specific Category_Id, basically replicate something like that:

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

However my dbcontext only have :

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

Thanks for any help.

like image 650
D.B Avatar asked May 26 '15 18:05

D.B


People also ask

What is many-to-many relationships in code first approach?

A many-to-many relationship occurs when multiple records in one table are associated with multiple records in another table. For example, a many-to-many relationship exists between Book and Category entities.

How do I code first in Entity Framework?

Step 1 − First, create the console application from File → New → Project… Step 2 − Select Windows from the left pane and Console Application from the template pane. Step 3 − Enter EFCodeFirstDemo as the name and select OK. Step 4 − Right-click on your project in the solution explorer and select Manage NuGet Packages…


3 Answers

You can do this:

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;

This way you will get the articles that satisfies the condition you want. This is the sql code that is generated by that 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))

Update

Another option could be using SelectMany extension method (as @Khaled pointed out) starting your query from Categories instead of Articles:

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

That would generate an Inner join instead of the EXIST that is product of Any extension method.

like image 90
octavioccl Avatar answered Oct 07 '22 08:10

octavioccl


How about

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

This should work fine (produce the right joined sql statement.)

like image 41
Khaled Rashad Avatar answered Oct 07 '22 10:10

Khaled Rashad


Example linq method syntax

int category_ID = 1;

var query = db.Articles
    .Where(a => a.Categories
    .Any(c => c.Category_ID == category_ID))
    .ToList();
like image 4
Mauricio Ferraz Avatar answered Oct 07 '22 10:10

Mauricio Ferraz