Linq to DocumentDB:按日期时间字段筛选
我正在使用LINQ来DocumentDB,目前我正试图通过datetime字段过滤返回的记录。我的质询如下:Linq to DocumentDB:按日期时间字段筛选,linq,azure-cosmosdb,Linq,Azure Cosmosdb,我正在使用LINQ来DocumentDB,目前我正试图通过datetime字段过滤返回的记录。我的质询如下: var mycollection = Client.CreateDocumentQuery<Test>(MyCollection.DocumentsLink) .Where(d => d.Time >= DateTime.Now) .AsEnumerable
var mycollection = Client.CreateDocumentQuery<Test>(MyCollection.DocumentsLink)
.Where(d => d.Time >= DateTime.Now)
.AsEnumerable();
发生此错误是因为我正在使用datetime字段进行筛选。如果我要对任何字符串字段进行过滤,这将非常有效。如何防止此错误?不支持
DateTime
时间,您必须将DateTime
转换为int,这样您的JSON如下所示(例如):
您需要使用JsonConverter
并将DateTime
属性视为历元。此代码是从中借用的
而.ToEpoch
扩展方法定义为:
public static class Extensions
{
public static int ToEpoch(this DateTime date)
{
if (date == null) return int.MinValue;
DateTime epoch = new DateTime(1970, 1, 1);
TimeSpan epochTimeSpan = date - epoch;
return (int)epochTimeSpan.TotalSeconds;
}
}
DocumentDB中的DateTime对象默认序列化为ISO 8601字符串格式,例如:“2016-08-08T22:10:50.000000 Z” 在这种情况下,您可以使用SQL语法而不是LINQ,因为不支持DateTime对象 请注意,您可以将EnableScanInQuery集作为查询中的FeedOptions传递给true,或者在时间字段上设置精度为-1的范围索引 你可以像David提到的那样将日期存储为历元,但你不必这样做 以下是您的查询结果: 字符串currentTime=DateTime.UtcNow.ToString(“o”) var myQuery=Client.CreateDocumentQuery(MyCollection.DocumentsLink, “从c中选择*,其中c.Time>='”+currentTime+“'”,新的FeedOptions{EnableScanInQuery=true})
.AsEnumerable() 你读过这个吗+我要写这封信。它使用ISO-8601字符串,这是我在DocumentDB中存储日期时间数据的建议。感谢您的建议,但我仍然收到相同的错误。或者,您可以使用ISO-8601字符串。我认为默认情况下,DateTime对象是以这种方式序列化的(尽管我认为它们没有正确地反序列化),然后需要在字段上放置一个精度为-1的字符串范围索引。这种方法的好处在于,它们在数据库中是人类可读的。有些人认为它效率较低,但我在实验中没有看到任何性能影响。
{
"Time": 1408318702
}
public class FooBar
{
[JsonConverter(typeof(EpochDateTimeConverter))]
public DateTime Time { get; set; }
}
public class EpochDateTimeConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer,
object value,
JsonSerializer serializer)
{
int seconds;
if (value is DateTime)
{
DateTime dt = (DateTime)value;
if (!dt.Equals(DateTime.MinValue))
seconds = dt.ToEpoch();
else
seconds = int.MinValue;
}
else
{
throw new Exception("Expected date object value.");
}
writer.WriteValue(seconds);
}
public override object ReadJson(JsonReader reader,
Type type,
object value,
JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.None || reader.TokenType == JsonToken.Null)
return null;
if (reader.TokenType != JsonToken.Integer)
{
throw new Exception(
string.Format("Unexpected token parsing date. Expected Integer, got {0}.",
reader.TokenType));
}
int seconds = (int)reader.Value;
return new DateTime(1970, 1, 1).AddSeconds(seconds);
}
}
public static class Extensions
{
public static int ToEpoch(this DateTime date)
{
if (date == null) return int.MinValue;
DateTime epoch = new DateTime(1970, 1, 1);
TimeSpan epochTimeSpan = date - epoch;
return (int)epochTimeSpan.TotalSeconds;
}
}