Azure cosmosdb 如何使用DocumentDb查询DateTimeOffset

Azure cosmosdb 如何使用DocumentDb查询DateTimeOffset,azure-cosmosdb,Azure Cosmosdb,假设我将记录插入以下模型的Azure DocumentDb中: public class Message { [JsonProperty(PropertyName = "tid")] public string Id { get; set; } [JsonProperty(PropertyName = "start")] public DateTimeOffset StartAt { get; set; } } 它们都自动存储为字符串。我希望能够查询Start

假设我将记录插入以下模型的Azure DocumentDb中:

public class Message
{
    [JsonProperty(PropertyName = "tid")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "start")]
    public DateTimeOffset StartAt { get; set; }
}
它们都自动存储为字符串。我希望能够查询
StartAt
,所以我在上面添加了一个RngeIndex。我使用Azure门户来验证索引是否正常工作

这样,我加载DocumentDb.NET SDK并尝试以下查询:

var since = DateTimeOffset.UtcNow.Subtract(duration);
return Client.CreateDocumentQuery<T>(Collection.DocumentsLink)
    .Where(m => m.AtStart > since)
    .AsEnumerable();
var-since=DateTimeOffset.UtcNow.Subtract(持续时间);
返回Client.CreateDocumentQuery(Collection.DocumentsLink)
.其中(m=>m.AtStart>since)
.AsEnumerable();
但是我得到了错误

[DocumentQueryException: Constant of type 'System.DateTimeOffset' is not supported.]
   Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitConstant(ConstantExpression inputExpression) +3204
   Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitBinary(BinaryExpression inputExpression, TranslationContext context) +364
   Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitBinary(BinaryExpression inputExpression, TranslationContext context) +349
   Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitScalarLambda(Expression inputExpression, TranslationContext context) +230
   Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitWhere(ReadOnlyCollection`1 arguments, TranslationContext context) +55
   Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitMethodCall(MethodCallExpression inputExpression, TranslationContext context) +799
   Microsoft.Azure.Documents.Linq.ExpressionToSql.Translate(Expression inputExpression, TranslationContext context) +91
   Microsoft.Azure.Documents.Linq.ExpressionToSql.TranslateQuery(Expression inputExpression) +46
   Microsoft.Azure.Documents.Linq.SQLTranslator.TranslateQuery(Expression inputExpression) +20
   Microsoft.Azure.Documents.Linq.<ExecuteAllAsync>d__7.MoveNext() +177
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +179
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +66
   System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) +30
   Microsoft.Azure.Documents.Linq.<GetEnumeratorTAsync>d__10.MoveNext() +632
[DocumentQueryException:不支持'System.DateTimeOffset'类型的常量。]
Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitConstant(ConstantExpression inputExpression)+3204
Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitBinary(二进制表达式inputExpression,TranslationContext上下文)+364
Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitBinary(BinaryExpression输入表达式,TranslationContext上下文)+349
Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitScalarLambda(表达式输入表达式,翻译上下文)+230
Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitWhere(ReadOnlyCollection`1参数,TranslationContext)+55
Microsoft.Azure.Documents.Linq.ExpressionToSql.VisitMethodCall(MethodCallExpression inputExpression,TranslationContext)+799
Microsoft.Azure.Documents.Linq.ExpressionToSql.Translate(表达式inputExpression,TranslationContext)+91
Microsoft.Azure.Documents.Linq.ExpressionToSql.TranslateQuery(表达式inputExpression)+46
Microsoft.Azure.Documents.Linq.SQLTranslator.TranslateQuery(表达式inputExpression)+20
Microsoft.Azure.Documents.Linq.d_u7.MoveNext()+177
System.Runtime.CompilerServices.TaskWaiter.ThrowForNonSuccess(任务任务)+179
System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务)+66
System.Runtime.CompilerServices.TaskWaiter.ValidateEnd(任务任务)+30
Microsoft.Azure.Documents.Linq.d_u10.MoveNext()+632

有没有一种方法可以在不更改基础模型的情况下执行类型安全查询?

您可以对日期执行范围查询,但不能作为“类型安全”查询

这是因为DocumentDB没有日期时间数据类型。相反,DocumentDB严格遵守支持的数据类型(字符串、数字、布尔值、数组、对象和Null)的规范。因此,当尝试使用LINQ提供程序直接查询DateTimeOffset时,会出现一个异常,
不支持类型为“System.DateTimeOffset”的常量

默认情况下,DocumentDB客户端SDK将datetime对象属性序列化为格式化字符串,如下所示:
2014-09-15T23:14:25.7251173Z
。在字符串上添加范围索引将允许您在日期上执行字符串范围查询。您可以序列化
var-since=DateTimeOffset.UtcNow.Subtract(持续时间)作为ISO 8601字符串在代码段中执行查询


查看此链接,了解有关使用日期的更深入讨论。请注意,该博客有点过时,因为从最初撰写博客文章时起,就添加了对字符串范围索引和查询的支持。

我建议通过将不同时间存储在不同的时区/偏移量中进行测试,并确保按预期排序。只是比较字符串只有在它们都在同一时区(即UTC ending
Z
)时才有效。此转换将丢弃捕获的时区/偏移信息,这些信息可能会对您的应用程序造成问题,更糟糕的是,如果您需要计算出历史事件的观测本地时间,则将来会出现问题。各国多年来都在改变时区规则,因此这项工作意义重大。在财务和审计应用程序上应用注意事项。