2011-04-07 80 views
4

我在我的数据库中有多对多的关系。两个结束表是BlogPost和Item,中间的表是ItemBlogPost。我需要找回与特定项目相关的所有BlogPosts。在SQL我会做这样的:实体框架中的多对多查询4

SELECT BlogPost.* 
FROM BlogPost 
    JOIN ItemBlogPost ON BlogPost.ID = ItemBlogPost.BlogPost_ID 
WHERE ItemBlogPost.Item_ID = @Item_ID 

在C#我有类似的东西:

IQueryable<BlogPost> itemBlogPosts = from b in connection.BlogPosts 
            where b.Items == item.ID 
            orderby b.Content.CreateDate descending 
            select b; 

然而,行标b.Items不给我的项目属性的列表和没有b.ItemBlogPost查看中间表。我也试过b.Items.Contains(item),但那也失败了。我如何在LINQ to EF4中完成这项工作?

+0

如果你建立了多对多的关系,它应该只是'item.BlogPosts',不是? – 2011-04-07 20:56:06

回答

22

这个什么:

var itemBlogPosts = from i in connection.Items 
        from b in i.BlogPosts // I suppose you have a nav. property on Item 
        where i.Id == itemId 
        select b; 

同样的查询可以通过还定义:

var itemBlogPosts = connection.Items 
           .Where(i => i.Id == itemId) 
           .SelectMany(i => i.BlogPosts); 
2

你能只是这样做:

var itemBlogPosts = connection.Items.Single(b => b.ID == item.ID).BlogPosts; 

由于您使用的EF它应该为您处理多对多映射,并且您应该在您的项目对象中将BlogPosts作为导航项目。

+0

该应该先加载一个项目,然后执行第二个查询来延迟加载相关的博客文章。 – 2011-04-07 20:43:05

+0

如果你不想'延迟加载,你可以使用Include()选项。 – 2011-04-07 20:44:16

0

如果:

  1. 您产生从数据库(这样模型一)
  2. 连接表恰好包含两个外键(无附加列)
  3. 的外键的典范以正确的方式分别设立了

然后:

  1. EF将为您生成包含所谓的“双方”导航属性的类。 BlogPost上的导航属性(Items的集合)和nav.prop。 (BlogPosts的集合)。

这样:

  1. 可以遍历对象图双向的。获取特定项目的所有博客帖子,或以其他方式获取某个博客帖子的所有项目。

所以,当你的手有你的特定项目,你只需做创建相关的相关博客文章的集合:

Item item = context.Items.Include("BlogPosts").FirstOrDefault<Item>(i => i.ID = someID) 

现在你有一个充满相关博客文章的集合的特定项目(如果有的话是与此项目相关)。