我有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 query来做这件事。
我的sql查询是
SELECT DISTINCT(PersonId) From PersonBooks
WHERE BookId IN (2, 3, 4)
GROUP BY PersonId
HAVING COUNT (*) = 3sql查询,如果工作正常。但我想使用linq query来实现这一点。任何帮助都将得到评价。
更新
这个查询对我来说是有效的,但我不认为它是优化的。有人能帮我优化这个查询吗?
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;发布于 2015-05-22 20:24:31
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});发布于 2015-05-22 21:04:06
像往常一样,人们跳到LINQ中的join语法,但你绝对应该使用导航属性:
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。它还会根据需要返回Persons,而不仅仅是It。
顺便说一句,如果你想让人们至少读一本(不是全部)书,你可以用Any代替All。
发布于 2015-05-22 20:37:06
试试这个。
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};https://stackoverflow.com/questions/30396376
复制相似问题