信用卡到期检查Linq C#

时间:2019-03-02 18:56:51

标签: c# asp.net-mvc linq

我的应用程序使用付款处理供应商自动为订阅的客户开帐单。我只保留有关卡有效期的信息以及自动计费的供应商参考号。我每天都想检查会员卡在30天内到期的情况。我正在运行一个后台进程来发送电子邮件提醒。我正在努力让Linq接受我的查询。到期日期以字符串形式存储在数据库中,例如,2019年3月为0319。我想知道是否有任何机会使它生效。如果可以的话,请协助。我的最后一招可能是将当前存储为字符串mmyy的到期日期格式化为正确的日期。

int mon = DateTime.Now.Month;
int yr = DateTime.Now.Year;
int days = DateTime.DaysInMonth(yr, mon);
int dy = DateTime.Now.Day;
var allCardExpiring = db.DirectDebits.Include(i => i.Customer).Where(a =>a.DdOk && a.Customer.PassOk &&  DateTime.DaysInMonth(Convert.ToInt32(a.DateExpiry.Substring(2, 4)), Convert.ToInt32(a.DateExpiry.Substring(0, 2)))+days-dy < 30).Select(a => a.DirectDebitId).Distinct().ToList();

1 个答案:

答案 0 :(得分:2)

这是一个很好的示例,表明您不应将数据库形成为操作员用来输入其输入的格式。如果您的数据库将ExpiryDate作为DateTime,则不会遇到此问题。当然,在操作员输入其到期日期时,您必须将其转换为DateTime,但是(1)比转换回日期更容易,并且(2)您更经常使用什么:查询ExpiryDate或更新它? / p>

如果您对此数据库感到困惑,那么我的建议是创建一个查询,在其中使用{{3}将MonthYear属性分为MonthYear }和DbFunctions.Left,然后使用DbFunctions.Right

在查询中将其转换为正确的DateTime

如果您需要其他函数的此转换,请考虑为此创建单独的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属性,而应公开要显示给外界的属性。