#c# #linq #entity-framework-4 #linq-to-entities
#c# #linq #entity-framework-4 #linq-to-entities
Вопрос:
У меня есть объект EF Holiday:
public class Holiday {
public int HolidayId {
get;
set;
}
public DateTime StartDate {
get;
set;
}
public DateTime EndDate {
get;
set;
}
public bool IsActive {
get;
set;
}
}
Мне нужно получить все записи, в которых есть хотя бы один день в текущем месяце.
Например:
StartDate = "2014-06-29"
EndDate = "2014-07-03"
Если текущий месяц — июль, то я должен получить эту запись, потому что после этого мне нужно будет создать List<int>
список всех дней, влияющих на текущий месяц. Итак, в последнем примере мне нужно будет создать List<int>
из:
1,2 и 3 июля.
Например:
StartDate = "2014-07-23"
EndDate = "2014-08-01"
Я также должен получить эту запись.
Я делал:
var holidays = Holidays.Where(h=> h.IsActive == true amp;amp; h.StartDate < currentDate amp;amp; h.EndDate > currentDate).ToList();
Но запрос не выполняет то, что мне нужно.
Есть какие-нибудь подсказки?
Как насчет этого:
.Where(h => h.IsActive == true amp;amp; (h.StartDate.Month == currentDate.Month || h.EndDate.Month == currentDate.Month)).ToList();
ОБНОВЛЕНО:
Это не сработает, если у меня есть диапазон дат, где месяц не равен currentDate.Месяц. Нравится:
StartDate = "2014-06-29"
EndDate = "2014-08-03"
Комментарии:
1. Что такое
currentDate
?2. currentDate — это сегодня.
3. Ваш второй пример будет работать просто отлично, но я предполагаю, что вы, вероятно, тоже захотите проверить
Year
.4. Я попробовал свой второй пример, но он не сработал, когда у меня есть, например, StartDate = «2014-06-23» и EndDate = «2014-08-01», потому что ни одна из этих дат месяц == currentDate. Месяц.
5. ваш первый пример должен был сработать…
Ответ №1:
Решение, которое сработало, это:
Возможно, это не самый чистый.
var holidays = Uow.HolidayRepository.GetAllReadOnly().Where(h => h.IsActive == true amp;amp; (h.StartDate.Month == currentDate.Month || h.EndDate.Month == currentDate.Month) || (currentDate.Month > h.StartDate.Month amp;amp; currentDate.Month < h.EndDate.Month)).ToList();
Ответ №2:
Ни одного из тестов недостаточно: если текущая дата находится в today, то в первом тесте будут пропущены любые диапазоны дат, которые не включают текущую дату, поэтому, если сегодня первое число месяца, любой диапазон дат, начинающийся со второго, хотя и действительный, не будет перехвачен. Кроме того, диапазоны одного дня — если вы не включаете время, не будут перехвачены, потому что даты начала и окончания могут быть равны текущей дате, но никогда не могут быть больше или меньше — зависит от того, как вы определяете свой диапазон дат.
Второй тест завершается неудачей, во-первых, потому что в каждом году есть месяцы с 1 по 12, поэтому вы будете выбирать записи не только за этот год, но и за все годы, а во-вторых, вы пропускаете любые периоды, которые начинаются и заканчиваются за пределами месяца.
Создание списка дней для сравнения не кажется эффективным минимальное количество запусков 28 максимум 31.
Итак, вам нужно протестировать диапазоны, которые либо начинаются в текущем месяце, либо заканчиваются в текущем месяце в соответствии с кодом Daniels, но, кроме того, вам нужно проверить, где дата начала находится до текущего месяца, а дата окончания — после текущего месяца, я думаю, это должно охватывать все случаи?
Ответ №3:
Я думаю, это подойдет, пожалуйста, попробуйте:
int month = DateTime.Now.Month;
var result = Holidays.AsEnumerable().Where(h => Enumerable.Range(h.StartDate.Month, (h.EndDate.Month - h.StartDate.Month) 1).Contains(month));
Комментарии:
1. LINQ для объектов не распознает систему метода. Коллекции. Общий. Метод IEnumerable`1[System.Int32] Range(Int32, Int32)’, и этот метод не может быть преобразован в выражение хранилища.
2. @VAAA разместите . ToList() после праздников.
3. Я думаю, что если я размещу . ToList() В этот момент я отправлю запрос в базу данных. Поэтому я приведу все записи.
4. @VAAA да, так и будет, поэтому вместо этого разместите . AsEnumerable()