我有一个包含数百万个归档值行的数据库表,这些行包含一个值(单个),两个整数id字段和一个datetime字段(以及一些与我想要构建的缓存无关的其他字段) 。表结构是固定的,我无法改变它。现在我想将所有行读入一个简单类的对象数组中,我希望将其保存在内存中以用于缓存。
为了保持低内存消耗,我想使用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
语句的范围内不起作用。所以我需要找到另一种方式。
一种方法是在.ToList()
语句之前插入一个.Select(..)
,这样我就可以访问我自己的函数,但这将是一个丑陋的解决方法,因为它从中获取了大量不必要的字段DB。
有没有办法以某种方式“转换”日期时间?
答案 0 :(得分:2)
首先你声明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
。
修改强>
为了应对实体框架,这可能有效:
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
的参考/导入。
答案 1 :(得分:0)
DATEDIFF(SECOND,{d '1970-01-01'}, GETUTCDATE())
这将返回sql中的unix秒。