在Select语句中将DateTime转换为Unix Timestamp?

3
我有一个数据库表格,包含数百万个已存档的值行,这些行由一个值(单一)、两个整数ID字段和一个日期时间字段组成(以及其他与我想要构建缓存无关的字段)。该表结构固定,不能更改。现在,我想将所有行读入一个简单类的对象数组中,该数组我想保留在内存中以供缓存使用。
为了保持内存消耗低,我想使用Unix时间戳代替日期时间对象。这也很有用,因为前端图表等连续使用这个缓存时也会原生地使用Unix时间戳。
对于缓存创建,我想直接从ArchiveElement中进行选择。这对大多数字段都有效,但我不知道如何在

它是否获取了很多不必要的字段?看起来你似乎想要拉取整个表格。 - Jonesopolis
数据库表还有一些我没有在这里提到的字段,只是为了简单起见。 - Rob
你所说的Unix时间戳是什么意思?你是指类似于1423748783这样的纪元时间吗? - DavidG
我的意思是自1970年1月1日以来的秒数。(所有时间均为UTC,转换为本地时间将在前端进行)。 - Rob
2个回答

3

首先,您需要声明Unix Epoch时间:

var unixEpoch = DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

现在在您的Select中,只需从您的日期值中减去时期,这将给出一个TimeSpan类型,您可以从中获取TotalSeconds,这是您需要的值。
ArchiveCache = db.ArchiveValues.Select(x => new ArchiveElement() {
    DataPointId = (UInt16)x.DataPointId,
    StationId = (UInt16)x.StationId,
    Value = (Single)x.Value,
    DateValue = (x.DateValue - unixEpoch).TotalSeconds
});

注意: 这里假设你的 DateValue 属性是一个双精度浮点数,你可能需要将其转换为 long

编辑

为了应对 Entity Framework,你可以尝试这样做:

ArchiveCache = db.ArchiveValues.Select(x => new ArchiveElement() {
    DataPointId = (UInt16)x.DataPointId,
    StationId = (UInt16)x.StationId,
    Value = (Single)x.Value,
    DateValue =  SqlFunctions.DateDiff("ss", unixEpoch, x.DateValue)
});

这可能需要引用/导入System.Data.Entity.SqlServer

这会抛出一个 System.ArgumentException (DbArithmeticExpression)。 - Rob
啊,我忘了这是Entity Framework。你可以在Select之前加上ToList()吗? - DavidG
1
如果我这样做,我也可以使用我的自定义函数;-) - Rob

0
DATEDIFF(SECOND,{d '1970-01-01'}, GETUTCDATE())

这将返回 SQL 中的 Unix 秒。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接