Это хороший пример, который показывает, что вам не следует формировать базу данных в формате, который операторы используют для ввода своих данных.Если бы ваша база данных имела бы ExpiryDate
как DateTime, у вас не было бы этой проблемы.Конечно, с учетом того, что когда операторы вводят дату истечения срока действия, вам придется конвертировать ее в DateTime, но (1) это проще, чем обратное преобразование, и (2) Что вы чаще делаете: запрашиваете ExpiryDate или обновляете его?
Если вы застряли в этой базе данных, то я бы посоветовал создать запрос, в котором вы разделите свое свойство MonthYear
на Month
и Year
, используя DbFunctions.Left и DbFunctions.Right , затем преобразуйте его в своем запросе в правильный DateTime, используя DbFunctions.CreateDateTime
Если вам нужно это преобразование для других функций, рассмотрите возможность создания отдельного IQueryableфункции для этого, так что вы можете использовать его повторно.
В качестве функции расширения для вашего DirectDebit, который принимает входную последовательность DirectDebits и возвращает последовательность DateTimeDirectDebit:
public static IQueryable<DateTimeDirectDebit> ToDateTimeDirectDebits(
this IQueryable<DirectDebit> directDebits)
{
return directDebits.Select(directDebit => new
{
// split ExpiryDate into a Month and a Year
ExpiryDate = new
{
Month = DbFunctions.Left(directDebit.DateExpire, 2),
Year = DbFunctions.Right(directDebit.DateExpire, 2),
}
DirectDebit = directDebit,
})
.Select(directDebit => new DateTimeDirectDebit
{
// create the ExpiryDate as DateTime
ExpiryDate = DbFunctions.CreateDateTime(
directDebit.ExpiryDate.Year,
directDebit.ExpiryDate.Mnth,
1, // first day of the month
...),
DirectDebit = directDebit.DirectDebit,
});
}
Вам также нуженфункция, которая возвращает DateTimeDirectDebits, срок действия которых истекает в течение определенного количества дней.Опять же, как метод расширения:
public static IQueryable<DateTimeDirectDebit> WhereExpiresWithinDays(
this IQueryable<DateTimeDirectDebit> source,
int nrOfDays)
{
DateTime now = DateTime.now;
DateTime limitDate = now.AddDays(nrOfDays);
return source.Where(directDebit => directDebit.ExpiryDate < limitDate);
}
Аналогично, вы можете захотеть, чтобы функция, которая возвращает все directDebits, срок действия которых истекает в следующем месяце, использует для этого DbFunctions.DiffMonths.
Использование:
using (var dbContext = new ...)
{
var directDebitsThatExpireNextMonth = dbContext.DirectDebits
.ToDateTimeDirectDebits
.WhereExpiresWithinDays(30)
.Select(...);
}
Приятно то, что используя эти LINQ-подобные методы расширения, вы можете скрыть, как структурирована ваша база данных, особенно части, которые вас не устраивают.Таким образом, ваш код не должен быть так сильно реструктурирован, если ваша база данных изменяется внутренне, особенно те функции, которые не используют эти изменения.
Конечно, для правильного сокрытия структуры базы данных, класс DateTimeDirectDebitsне следует выставлять свойство DirectDebits, а только свойства, которые вы хотите показать внешнему миру.