Entity Framework 中的复杂 DateTime 查询

Complex DateTime query in Entity Framework

我想问一下如何在 Entity Framework 中编写一个复杂的 DateTime 查询,如下所示:

我正在使用此代码:

Func<DateTime, DateTime> calculate24HoursLater = (date) =>
{
    if (date.DayOfWeek == DayOfWeek.Friday)
        return date.AddDays(3);

    if (date.DayOfWeek == DayOfWeek.Saturday)
        return date.AddDays(3).Date;

    if (date.DayOfWeek == DayOfWeek.Sunday)
        return date.AddDays(2).Date;

    return date.AddDays(1);
};

var unactionedEnquiries = 
    dataContext.ContactedBrokerEnquiries
        .Include("ContactedBrokers")
        .Where(
            x => x.ContactedBrokers.All(c => c.Status == (byte)LeadStatus.Rejected) || 
                x.ContactedBrokers.Any(c => c.Status == (byte)LeadStatus.New && calculate24HoursLater(c.CreatedDate) < DateTime.Now)
        ).OrderByDescending(c => c.CreatedDate);

结果unactionedEnquiries,我预计它应该是IQueryable。这意味着 SQL 服务器在我的下一条语句

之前不会执行

但是,我在 calculate24HoursLater(c.CreatedDate) < DateTime.Now) 上遇到异常 此语句无法转换为 SQL 语句。我知道原因,但我不知道如何在 Entity Framework 查询

中写 rule

重要提示:我不喜欢将所有数据推送到 RAM 中然后使用该条件进行过滤。理想情况下,它应该在 SQL-Server

你能告诉我如何在 SQL-EF 语句中写它们吗?

您可能想看看是否可以使用 SQLFunctions 可用于在 LINQ 查询中执行日期操作的方法

示例(未测试)尝试用以下内容替换您的 Func 定义:

Func<DateTime, DateTime> calculate24HoursLater = (date) =>
{
    if (date.DayOfWeek == DayOfWeek.Friday)
        return SqlFunctions.DateAdd("day", 3, date).Value;

    if (date.DayOfWeek == DayOfWeek.Saturday)
        return SqlFunctions.DateAdd("day", 3, date).Value;

    if (date.DayOfWeek == DayOfWeek.Sunday)
        return SqlFunctions.DateAdd("day", 2, date).Value;

    return SqlFunctions.DateAdd("day", 1, date).Value;
};

正如我所见here @andrew 的天才回答,你可以这样做:

var calcDate = DateTime.Now.AddHours(-24);

var unactionedEnquiries = 
    dataContext.ContactedBrokerEnquiries
        .Include("ContactedBrokers")
        .Where(
            x => x.ContactedBrokers.All(c => c.Status == (byte)LeadStatus.Rejected) || 
                x.ContactedBrokers.Any(c => c.Status == (byte)LeadStatus.New && c.CreatedDate < calcDate)
        ).OrderByDescending(c => c.CreatedDate);