【问题标题】:Can't compare dates using SQLite with EF6无法使用 SQLite 与 EF6 比较日期
【发布时间】:2016-01-13 07:07:20
【问题描述】:

我正在尝试在 SQLite 数据库上使用 Linq to Entities 比较日期。以下代码有效,但我需要修剪时间部分以获得正确的结果。

return (from c in Context.Car
        join d in Context.Driver on c.CarID equals d.DriverID
        join r in Context.Rides on c.CarID equals r.RideID into rideJoin
        from rides in rideJoin.DefaultIfEmpty()
        where c.IsActive && d.IsActive 
        group rides by new { c.CarID, d.FullName, d.HireDate, d.FirstPayRiseDate } into grp
        select new MyCustomClass
        {
            CarID = grp.Key.CarID,
            Driver = grp.Key.FullName,
            NumberOfRides = grp.Count(x => x != null && x.RideDate >= grp.Key.HireDate && x.RideDate <= grp.Key.FirstPayRiseDate)
        }).OrderBy(x => x.Driver ).ToList();

我已经尝试过像这样使用System.Data.Entity.DBFunctions,但我得到了这个错误:

NumberOfRides = grp.Count(x => x != null && DbFunctions.TruncateTime(x.RideDate) >= grp.Key.HireDate && DbFunctions.TruncateTime(x.RideDate) <= grp.Key.FirstPayRiseDate)

SQL 逻辑错误或缺少数据库没有这样的功能:TruncateTime

DBFunctions.DiffDays() 也出现同样的错误


我也尝试过像这样转换为 Date 并收到此错误:

NumberOfRides = grp.Count(x => x != null && x.RideDate.Date >= grp.Key.HireDate && x.RideDate.Date <= grp.Key.FirstPayRiseDate)

LINQ to Entities 不支持“日期”。仅支持初始化器、实体成员和实体导航属性

什么给了?我应该如何使用 SQLite 在 Linq to Entities 中执行日期函数??

【问题讨论】:

  • SQLite 没有名为TruncateTime 的时间截断函数,而是使用内部的DATE() 函数来检索date 值的date 部分。
  • @Dai 你是如何在 linq 中做到这一点的?
  • 也许@Dai 的意思是在 SQLite 中创建一个视图,其中的列使用 DATE() 来隔离日期部分,然后使用视图而不是表。我明白你的意思:RideDate.Date in LINQ to Entities;使用 LINQ to SQL 对我来说效果很好。也许另一种可能性是调整您的 Ride 对象以添加一个仅限日期的属性作为RideDate.Date,然后在您的 LINQ 表达式中使用它。 (不过只是猜测。)
  • 另外,this question 看起来很相似。也许它可能会有所帮助。
  • @GordThompson That question 帮助我解决了 1 个问题。不幸的是,为了比较另一个查询的两个日期,它涉及撤回太多的数据库。另外,我需要在第一部分执行 ToList(),否则我会遇到同样的错误。

标签: c# entity-framework linq sqlite datetime


【解决方案1】:

您如何在数据库中存储日期?作为unix时间积分器? 在那个 acse 中,您可以修改您的连接字符串以包含以下配置设置,这将使通过 EF 读取日期时间值变得容易。

datetimeformat=UnixEpoch;datetimekind=Utc

类似:

data source=&quot;|DataDirectory|\data.sqlite&quot;;datetimeformat=UnixEpoch;datetimekind=Utc

参考:https://stackoverflow.com/a/24323591/3660930

【讨论】:

  • 这没有帮助。日期有效。使用 sqlbrowser 查询可以正常工作。但我需要它使用 linq
【解决方案2】:

我需要修剪时间部分以获得正确的结果

不,你没有。如果您想包含从 startDateendDate 的行,那么只需使用

... && x.RideDate >= startDate && x.RideDate < endDate.AddDays(1)

(请注意,第二个比较现在“严格小于”。)

【讨论】:

  • 这是我在写问题时提出的解决方案。不过,这是一种解决方法,我当然应该能够进行一些日期操作吗?
  • 是的,但这是一个很好的解决方法,因为它增加了底层 SQL 查询的 WHERE 条件为 sargable 的机会。
  • Sargable 很好。但是,当我尝试比较 2 个数据库日期时,这将不起作用。我会更新问题以反映这一点。
猜你喜欢
  • 2013-04-20
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 2019-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多