2016-02-13 46 views
2

我想查询文档上的更新时间戳记_ts以获取自某个时间段以来未发生变化的文档。DocumentDB如何在_TS上进行LINQ查询?

当我创建了蔚蓝色的门户网站这个工作的选择查询:

SELECT TOP 10 c.id FROM c WHERE c._ts < 6.35909919217878E+17 

的怪异号与日期时间对象创建的蜱,见下文。

但是,当我尝试通过LINQ创建它时,它不会执行,因为您没有_ts,而是将Timestamp作为DateTime对象。当我尝试输入完整的DateTime对象来与Timestamp进行比较时,它会崩溃,并说它不支持它。所以,我试试这个:

DocRepo.Get(x => x.Timestamp.Ticks < CloseDate.Ticks); 

这导致到什么,当我观看了查询执行它有这个作为一个选择查询:

SELECT * FROM root WHERE root[\"_ts\"][\"Ticks\"] < 6.35909943137688E+17 

是否有可能在_TS时间戳查询还是我必须有一个额外的updatedAt字段来做到这一点,这似乎是多余的。

回答

4

你的查询有几个问题。在您的第一个查询中,您正在比较“蜱”(百万分之一秒 - see here)与_ts值,这很可能会返回集合中的所有文档,因为_ts值是以秒为单位测量的POSIX(Unix)时间see here。他们也不是基于同一个时代。 Unix值从午夜1,1,1970开始,其中Ticks从午夜开始1,1,0001因此,_ts值总是比Ticks值小得多(不要提到1969年!)。您需要将日期转换为Unix时间值。你可以创建一个扩展方法来帮助你做到这一点:

public static long ToUnixTime(this DateTime date) 
    { 
     var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 
     return (long)(date - epoch).TotalSeconds; 
    } 

对于LINQ的声明,你不能(不幸)把日期时间为LINQ查询,因为DateTime值不会转换为一个常量(这是你得到的错误)。因此,在这两种情况下,您都不能很容易地比较_ts值或TimeStamp值。

那该怎么办?那么,在看DocumentDB SDK,如果你看一下时间戳的定义,你会看到以下内容:

// Summary: 
    //  Gets the last modified timestamp associated with the resource. 
    [JsonConverter(typeof(UnixDateTimeConverter))] 
    [JsonProperty(PropertyName = "_ts")] 
    public virtual DateTime Timestamp { get; internal set; } 

所以默认情况下,SDK是_TS值转换为DateTime,并通过时间戳字段将它暴露。根据您的DocRepo返回的类型,您可以执行一些操作。如果是默认的文件类型,你可以创建一个新的类,从的Docment型像这样继承:

public class MyDocument : Document 
{ 
    public long _ts 
    { 
     get; set; 
    } 
} 

如果这是你自己的自定义类,然后就在_TS字段添加到您的类。无论哪种方式,如果_ts字段存在,DocumentDB将填充该字段。然后,如果您添加ToUnixTime扩展方法,你可以撰写你的Linq查询是这样的:

DocRepo.Get(x => x._ts < CloseDate.ToUnixTime()); 

这可能不是一个完美的解决方案,有人(希望)可能会拿出一个更好的解决办法,但我已验证它对我自己的DocumentDB集合有效。

希望这会有所帮助。

0

这是我使用Unix时间戳转换成DateTime格式,我们可以在C#中很容易理解:

public DateTime TimeStamp 
     {    
      get 
      { 
       return DateTimeOffset.FromUnixTimeSeconds(int.Parse(_ts)).DateTime; 
      } 
     } 

希望这有助于。