我有3个表,Person
| Book
| PersonBook
PersonBook
表是Person
和Book
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;
答案 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};