#c# #asp.net #linq
#c# #asp.net #linq
Вопрос:
Я хотел бы знать, как выполнить запрос, который возвращает строки, которые не имеют совпадений.
Например: Запрос должен возвращать список людей, которые не брали напрокат ни одного фильма с заданной даты.
Я написал этот код, но мне помогло предложение foreach.
Заранее спасибо, Миша.
// dt is a date from the user
public IEnumerable inActiveRenters(DateTime dt)
{
var rents = from r in myDb.Rents
where r.RentStart > dt
select r;
List<Member> memberList = new List<Member>();
foreach (Member m in myDb.Members)
{
bool notRent = true;
foreach (Rent r in rents)
{
if (r.MemberID == m.MemberID)
{
notRent = false;
}
}
if (notRent)
{
memberList.Add(m);
}
}
var list = from m in memberList
select new { m.MemberID, m.FirstName };
return list;
}
Ответ №1:
Участники, которые не брали напрокат ни одного фильма:
var rentsSinceDate = myDb.Rents.Where(r => r.RentStart > dt);
var notRentedAnyMovie = myDb.Members
.Where(m => !rentsSinceDate.Any(r => r.MemberID == m.MemberID))
.Select(m => new { m.MemberID, m.FirstName });
Ответ №2:
myDb.Members
.Join(myDb.Rents
.Where(r => r.RentStart < dt),
m => m.MemberID,
r => r.MemberID,
(m, r) => m);
Ответ №3:
Micha,
AFAIK, есть «несколько» способов сделать это, в зависимости от того, какую базу данных вы используете.
-
СОЕДИНЕНИЕ СЛЕВА, ГДЕ NULL. Например
SELECT c.* FROM customer c LEFT JOIN rentals r ON r.cutomer_id is null WHERE r.date >= ${theCutOffDate}
-
НЕ СУЩЕСТВУЕТ
SELECT c.* FROM customer c WHERE NOT EXISTS( SELECT 1 FROM rentals WHERE date >= ${theCutOffDate} )
-
НЕ В
SELECT c.* FROM customer c WHERE c.customer_id NOT IN( SELECT customer_id FROM rentals WHERE date >= ${theCutOffDate} )
Пожалуйста, обратите внимание: вполне могут быть способы, которых я не видел (пока).
Вариант 1: left join
, вероятно, поддерживается наиболее единообразно, поэтому я бы рекомендовал его (в отсутствие другой соответствующей информации, например, какую СУБД freeken вы используете.)
Ваше здоровье. Кит.
Комментарии:
1. Все допустимые ответы в TSQL, но я думаю, что нам нужны решения Linq
2. Да, я вроде как понял это постфактум… Я не очень умный 😉
Ответ №4:
Это должно сработать:
from r in myDb.Rents.Where(p => !myDB.Members.Any(m => m.MemberID == p.MemberID))
where r.RentStart > dt
select r;