запрос linq на отсутствие совпадающих строк

#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, есть «несколько» способов сделать это, в зависимости от того, какую базу данных вы используете.

  1. СОЕДИНЕНИЕ СЛЕВА, ГДЕ NULL. Например

     SELECT c.* 
    FROM customer c 
    LEFT JOIN rentals r 
    ON r.cutomer_id is null 
    WHERE r.date >= ${theCutOffDate}
      
  2. НЕ СУЩЕСТВУЕТ

     SELECT c.* 
    FROM customer c 
    WHERE NOT EXISTS(
      SELECT 1 
      FROM rentals 
      WHERE date >= ${theCutOffDate}
    )
      
  3. НЕ В

     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;