C # Linq для объектов получает записи, где диапазон дат содержит даты текущего месяца

#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()