在where子句中将数字转换为日期时间的LINQ查询

r7xajy2e  于 2022-12-06  发布在  其他
关注(0)|答案(1)|浏览(108)

我有一个数据类型为numeric的字段,并且在其中存储了hour值。现在我想用数值字段减去DateTime字段的小时数,并将其与DateTime.Now()进行比较。我在LINQ查询的where子句中使用了以下逻辑:'private List GetInterviewExamSlots(int programPreferenceId,string lookuptype){ var currentDateTime = DateTime.UtcNow;

var schedules = uow.RepositoryAsync<CoC_Schedule_Entry>()
            .Queryable()
            .AsNoTracking()
            .OrderByDescending(x=> x.Start_Datetime)
            .Where(x => x.Capacity != null &&
            x.Capacity != 0  &&
            (x.Start_Datetime).AddHours((double)- x.Event_Registration_Deadline) > currentDateTime &&
            x.Fully_Booked_Flag != Constants.YesFlag &&
            x.CoC_Schedule_Entry_Type.Schedule_Entry_Type_Code.Equals(lookuptype) &&
            x.CoC_Lookup3.Hidden_Value.Equals(LookupCodes.OpenHiddenValue) 
            && (x.Program_Preference_ID == programPreferenceId
            ||
            x.Program_Preference_ID == null))
            .Select(x => new ............`

但它会引发异常:LINQtoEntities无法识别.“AddHours”方法,并且此方法无法转换为存储表达式。

kgsdhlau

kgsdhlau1#

并不是所有可以用C#表达的东西都可以翻译成商店的语言。这取决于特定的商店和LINQ提供程序(如sqlserver的实体框架)。在您的情况下,提供程序不能翻译AddHours函数调用。
要克服这一点,您可以
1.从你的查询中删除方法调用,将结果转换成可以通过Linq2Objects查询的东西(例如,通过添加.ToList()将你的(中间)结果转换成List<...>),然后再次查询它。现在没有什么需要被转换,AddHours(和任何其他函数调用)将工作。
这可能会消耗许多本地资源,具体取决于您的数据。

var preSelectedSchedules = uow.RepositoryAsync<CoC_Schedule_Entry>()
    .Queryable()
    .AsNoTracking()
    .OrderByDescending(x=> x.Start_Datetime)
    .Where(x => x.Capacity != 0  
        && x.Fully_Booked_Flag != Constants.YesFlag
        && x.CoC_Schedule_Entry_Type.Schedule_Entry_Type_Code.Equals(lookuptype)
        && x.CoC_Lookup3.Hidden_Value.Equals(LookupCodes.OpenHiddenValue)
        && (x.Program_Preference_ID == programPreferenceId
            || x.Program_Preference_ID == null))
    .ToList();

var schedules = preSelectedSchedules
    .Where(x => x.Start_Datetime.AddHours(-x.Event_Registration_Deadline) > currentDateTime)
    .Select(...);

1.用商店的语言提供一个查询(如果我们讨论的是sql,就像视图),它返回所需的数据,您可以使用它作为查询的数据源。
如果x.Event_Registration_Deadline的不同值很少,也可以尝试另一种方法:

  • 选择x.Event_Registration_Deadline的所有非重复值
  • 对于每个值,计算var theshold = currentDateTime.AddHours(<value>);
  • 使用.Where(x => x.Start_Datetime > threshold)执行查询

相关问题