2015-05-26 6 views
28

Как я могу запросить отношения «многие ко многим», используя сначала код Entity Framework и linq? Проблема в том, что EF автоматически создает таблицу отношений. Итак, у меня его нет в моем контексте.Запросить отношение «многие ко многим» с linq/Entity Framework. CodeFirst

Это реляционная модель:

enter image description here

Мне нужен список статей для конкретного CATEGORY_ID, в основном повторить что-то подобное:

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

Однако мой DbContext только:

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

Спасибо за любые Помогите.

ответ

32

Вы можете сделать это:

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; 

Таким образом, вы получите статьи, который удовлетворяет условию вы хотите. Это SQL-код, который генерируется этим запросом:

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

Благодаря таким much.It работал идеально. –

+1

Это неверно, EF недостаточно умен, чтобы использовать соединения. Вместо этого он будет создавать инструкцию EXISTS. Здесь может быть проблема с производительностью. – Talon

+0

@Talon, теперь я протестировал этот запрос, и это правда, что поставщик EF 6.x Linq генерирует 'Exists' вместо' join'. Спасибо за ответ. Согласились с вами о производительности, но если вы опустите таблицу соединений как часть вашей модели, это единственный способ сделать это. – octavioccl

5

Как насчет

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

Это должно работать нормально (произвести правильный присоединился к SQL Statement.)

+0

где находится 'a'? Не могли бы вы пояснить, что вы имеете в виду, пожалуйста. –

+0

Это должно быть 'c => c.Arts'. Это приведет к объединению каждого списка статей категорий, выбранных из запроса Where. –

+0

Отлично, это правильное решение. EF генерирует INNER JOIN вместо WHERE EXISTS. С EXISTS очень медленно. –

1

Я просто побежал в этот и решил, что я опубликую решение, которое я нашел для тех, кто наткнулся на эту страницу. Это создает 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

Если вы просто хотите всю таблицу, включая все отношения, может быть, попробовать что-то вроде этого:

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

Пример метода LINQ синтаксис

int category_ID = 1; 

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