Linq, левое соединение и даты
Поэтому моя ситуация такова, что у меня есть модель linq-to-sql, которая не позволяет датам быть нулевыми в одной из моих таблиц. Это предназначено, потому что база данных не допускает пустые значения в этом поле. Моя проблема в том, что когда я пытаюсь написать запрос Linq с этой моделью, я больше не могу выполнить левое соединение с этой таблицей, потому что дата не является полем 'nullable', и поэтому я не могу сравнить его с "Nothing".
Пример: есть таблица Movie {ID,MovieTitle} и таблица Showings, {ID,MovieID,ShowingTime,Location}
Сейчас я пытаюсь написать заявление, которое вернет все те фильмы, у которых нет показов. В T.SQL это будет выглядеть так:
Select m.*
From Movies m Left Join Showings s On m.ID = s.MovieID
Where s.ShowingTime is Null
Теперь в этой ситуации я мог бы проверить на Null в поле "Местоположение", но это не то, что я имею в действительности (просто упрощенный пример). Все, что у меня есть, - ненулевые даты.
Я пытаюсь написать в Linq:
From m In dbContext.Movies _
Group Join s In Showings on m.ID Equals s.MovieID into MovieShowings = Group _
From ms In MovieShowings.DefaultIfEmpty _
Where ms.ShowingTime is Nothing _
Select ms
Однако я получаю сообщение об ошибке
Оператор "Is" не принимает операнды типа "Дата". Операнды должны быть ссылочными или обнуляемыми типами.
Есть ли способ обойти это? Модель верна, в таблице Showings:ShowTime никогда не должно быть нулевого значения. Но если вы выполняете левое соединение, и для определенного фильма нет времени показа, тогда ShowTime НЕ ДОЛЖЕН быть ничем для этого фильма...
Спасибо всем за вашу помощь.
2 ответа
Использование левого соединения не очень помогает вам здесь. Поскольку в правой таблице никогда не может быть результатов, вы можете просто получить левую и только левую таблицы. Это простой запрос "не в" / "не существует":
From m in dbContext.Movies _
Where Not dbContext.Showings.Any(Function(s) s.MovieID = m.MovieID) _
Select m
Если в таблице Showings нет записи, тогда весь объект в запросе должен быть ничем. Дата никогда не должна вступать в игру при таком сценарии. Левое объединение будет написано так, выбирая только фильмы, показ которых отсутствует
Dim query = From m In dbContext.Movies _
Group Join s In dbContext.Showing On m.ID Equals s.MovieID Into g = Group _
From item In g.DefaultIfEmpty() _
Where item Is Nothing _
Select m