Простой, но специфичный
Вы можете добавить метод расширения, подобный этому:
public static class DateTimeExtensions
{
public static bool IsBetween(this DateTime thisDateTime, DateTime start, DateTime end)
{
return thisDateTime >= start && thisDateTime <= end;
}
}
, который можно тестировать отдельно.
Затем вы можете использовать это в любом поле DateTime, которое вы хотите проверить.Например:
var start = new DateTime(2017, 1, 1);
var end = new DateTime(2017, 12, 31, 23, 59, 59);
IList<Contract> contracts = new List<Contract>(); // or anything enumerable
var contractsSignedBetween = contracts.Where(x => x.SignDate.IsBetween(start, end));
var contractsReleasedBetween = contracts.Where(x => x.ReleaseDate.IsBetween(start, end));
(Обратите внимание, что для даты начала и времени установлено время 00:00:00, а для даты окончания - время 23:59:59 [не стесняйтесь также включать миллисекунды], так что время за последний день включено.)
Создание этого многоразового использования
Если вам понадобится сделать это много, вы можете сделать расширение длячто
public static class EnumerableContractsExtensions
{
public static IEnumerable<Contract> SignedBetween(this IEnumerable<Contract> contracts, DateTime start, DateTime end)
{
return contracts.Where(x => x.SignDate.IsBetween(start, end));
}
}
и использовать его вот так
var contractsSignedBetween = contracts.SignedBetween(start, end);
, который также может быть проверен модулем изолированно.
Более гибкий, но специфичный
Используйте выражение, чтобы сказать, какую дату вы хотите ...
public static class EnumerableContractsExtensions
{
public static IEnumerable<Contract> Between(this IEnumerable<Contract> contracts, Func<Contract, DateTime> selector, DateTime start, DateTime end)
{
return contracts.Where(x => selector(x).IsBetween(start, end));
}
}
, а затем:
var contractsSignedBetween = contracts.Between(x => x.SignDate, start, end);
var contractsReleasedBetween = contracts.Between(x => x.ReleaseDate, start, end);
Гибкое и универсальное
Пройдите всю свинью и сделайте это в общем (хотя вы не можете сделать это методом расширения, потому что это универсально):
public static class EnumerableExtensions
{
public static IEnumerable<T> Between<T>(IEnumerable<T> items, Func<T, DateTime> selector, DateTime start, DateTime end)
{
return items.Where(x => selector(x).IsBetween(start, end));
}
}
еще раз, это можно проверить самостоятельно и может бытьиспользуется следующим образом:
IList<Contract> contracts = new List<Contract>();
IList<PersonalCheck> personalChecks = new List<PersonalCheck>();
var contractsSignedBetween = EnumerableExtensions.Between(contracts, x => x.SignDate, start, end);
var checksSignedBetween = EnumerableExtensions.Between(personalChecks, x => x.SignDate, start, end);
Сделать его IQueryable
Чтобы сделать эту работу как IQueryable
, подход должен перейти кn дерево выражений , поскольку LINQ to Entities не знает, как преобразовать метод в SQL.
public static IQueryable<TSource> Between<TSource, TKey>(
this IQueryable<TSource> source,
Expression<Func<TSource, TKey>> keySelector,
TKey low,
TKey high)
where TKey : IComparable<TKey>
{
Expression key = keySelector.Body;
Expression lowerBound = Expression.LessThanOrEqual(Expression.Constant(low), key);
Expression upperBound = Expression.LessThanOrEqual(key, Expression.Constant(high));
Expression and = Expression.AndAlso(lowerBound, upperBound);
Expression<Func<TSource, bool>> lambda =
Expression.Lambda<Func<TSource, bool>>(and, keySelector.Parameters);
return source.Where(lambda);
}
, который все равно будет использоваться следующим образом:
var contractsSignedBetween = contracts.Between(x => x.SignDate, start, end);
И это работает для других вещей, кроме DateTime
с.Надеюсь, это поможет.