根据多对多关系表

时间:2015-05-22 12:10:44

标签: c# sql-server linq many-to-many entity-framework-6

我有3个表,Person | Book | PersonBook
PersonBook表是PersonBook

之间的relaton表
Person          Book                    PersonBooks
Id   Name       Id     Name             Id   PersonId   BookId
1    rick        1      SQL              1     1          1
2    phil        2      Asp.Net          2     1          3
3    scott       3      MySql            3     2          4 
                 4      C#               4     3          2
                                         5     3          3
                                         6     3          4

我希望得到读书ID为2,3,4的人。因此结果应为3。

我试过什么

我设法编写sql查询来获取结果。但是我想要Linq查询 我的SQL查询是

SELECT DISTINCT(PersonId) From PersonBooks
WHERE BookId IN (2, 3, 4)
GROUP BY PersonId
HAVING COUNT (*) = 3

sql查询如果工作正常。但我想使用linq查询。任何帮助都将得到满足

更新

此查询适用于我但我不认为它已经过优化。任何人都可以帮我优化这个查询。

from p in Context.Book where (Context.PersonBooks.Where(x => personIds.Contains(x.PersonId))
    .GroupBy(x => x.BookId)
    .Where(x=>x.Count() == personIds.Count)
    .OrderByDescending(x => x.Count())
    .Select(x => x.Key).ToList()).Contains(p.BookId) select p;

3 个答案:

答案 0 :(得分:4)

var person = (from p in PersonBooks
                  join b in Book on p.BookId equals b.BookId
                  where b.BookId  IN (2, 3, 4)
                  select new { p.PersonId});

答案 1 :(得分:2)

像往常一样,人们跳转到LINQ中的语法连接,但你绝对应该使用导航属性:

var ids = new[] { 2, 3, 4 };
var persons = from p in db.Persons
              where p.PersonBooks.All(pb => ids.Contains(pb.BookId))
                 && p.PersonBooks.Count() == 3
              select p;

这会转换为EXIST子句,因此您不再需要Distinct。它还会根据您的需要返回Person,而不仅仅是Ids。

顺便说一句,如果您想要阅读至少一本(并非所有)图书的人,可以将All替换为Any

答案 2 :(得分:0)

试试这个......

from bp in BookPerson
join p in person on p.personId== bp.personId
join b in books on b.bookId == bp.bookId
where b.bookId = 1 && b.bookId = 2 && b.bookId = 3
group p by bp.personId into p
select new {g.personId};