我确实有一个数据库表,其中包含数百万个存档值行,其中包含一个值(单个)、两个整数 id 字段和一个日期时间字段(以及一些与我要构建的缓存无关的其他字段) .表结构是固定的,我不能改变它。现在我想将所有行读入一个简单类的对象数组中,我想将其保留在内存中以用于缓存目的。
为了保持低内存消耗,我想使用 unix 时间戳而不是 datetime 对象。这也很有用,因为将连续使用此缓存的前端图表等本身也可以使用 Unix 时间戳。
对于缓存创建,我想选择直接进入ArchiveElement。这适用于大多数领域,但我不知道如何在 select 语句中动态创建 Unix 时间戳:
ArchiveCache = db.ArchiveValues.Select(x => new ArchiveElement() {
DataPointId = (UInt16)x.DataPointId,
StationId = (UInt16)x.StationId,
Value = (Single)x.Value,
DateValue = x.DateValue // <-- Here I want to cast into Unix Timestamp
});
这是 ArchiveElement 类:
public class ArchiveElement
{
public UInt32 DateValue;
public UInt16 DataPointId;
public UInt16 StationId;
public Single Value;
}
我的应用程序中确实有一个函数可以将 DateTime
转换为 Unix TimeStamp,但这在 select
语句的范围内不起作用。所以我需要另辟蹊径。
一种方法是在 .Select(..)
语句之前插入一个 .ToList()
,这样我就可以访问我自己的函数,但是这将是一个丑陋的解决方法,因为它从数据库中获取了很多不必要的字段。
有没有办法以某种方式“就地”转换日期时间?
最佳答案
所以首先声明 Unix 纪元时间:
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
属性是 double 型,您可能需要将其转换为 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
。
关于c# - 在 Select 语句中将 DateTime 转换为 Unix 时间戳?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28478964/