CosmosDB 中有以下测试数据。
{
"LastSuccessfulDeployment": "2022-10-08T01:30:30.0000000Z",
},
{
"LastSuccessfulDeployment": "2022-10-08T01:30:30.3816486Z",
}
搜索“2022-10-08T01:30:30.0000000Z”不会返回任何记录,而搜索“2022-10-08T01:30:30.3816486Z”时会返回记录。
protected override IQueryable<Component> ApplyFiltersOnQueryInternal(IQueryable<Component> query, IFilter<Component> filter)
{
if (filter == null)
return query;
var componentFilter = (filter as ComponentFilter)!;
if (componentFilter.LastSuccessfulDeployment.HasValue)
query = query.Where(x => x.LastSuccessfulDeployment == componentFilter.LastSuccessfulDeployment);
return query
.Skip((componentFilter.CurrentPage - 1) * componentFilter.PageSize)
.Take(componentFilter.PageSize);
}
EntityQueryable 调试视图:
-- @__componentFilter_LastSuccessfulDeployment_0='08/10/2022 01:30:30'
SELECT c
FROM root c
WHERE ((c["Discriminator"] = "Component") AND (c["LastSuccessfulDeployment"] = @__componentFilter_LastSuccessfulDeployment_0))
-- @__componentFilter_LastSuccessfulDeployment_0='12/10/2022 15:18:14'
SELECT c
FROM root c
WHERE ((c["Discriminator"] = "Component") AND (c["LastSuccessfulDeployment"] = @__componentFilter_LastSuccessfulDeployment_0))
```Code
如果查询中使用的日期时间没有毫秒,cosmosdb v3 SDK 中的 Linq 查询似乎不会将毫秒放入查询中。
Linq 查询,例如
var testTime = DateTime.Parse("2023-04-16T21:53:56Z").ToUniversalTime();
query
.Where(x => x.MyTime >= testTime)
.OrderBy(x => x.MyTime)
.Take(1);
将生成以下SQL
SELECT TOP 1 VALUE root FROM root WHERE ((root["MyTime"] >= "2023-04-16T21:53:56Z")) ORDER BY root["MyTime"] ASC
虽然我在 cosmosdb 中有一条带有
2023-04-16T21:53:56.5Z
的记录,但当查询时间没有毫秒时,该记录不会返回。
将查询更改为
时SELECT TOP 1 VALUE root FROM root WHERE ((root["MyTime"] >= "2023-04-16T21:53:56.0Z")) ORDER BY root["MyTime"] ASC
记录被返回。在我看来,cosmosdb 会根据查询中日期时间的精度来选择查询精度。
您可以全局更改 Newtonsoft JSON 序列化器的日期,或在每个属性的注释中更改。下面示例中的格式将始终包含 7 ms 数字。
JsonConvert.DefaultSettings = () =>
{
var settings = new JsonSerializerSettings()
{
Converters = new List<JsonConverter>()
{
new IsoDateTimeConverter()
{
DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffffffZ"
}
}
};
return settings;
};
即使您定义了不使用 newtonsoft 的自定义序列化器,这也可以工作。自定义序列化程序不用于 LINQ 查询。它总是使用 Newtonsoft 来实现这一点。
请注意,您还应该将日期时间存储为
yyyy-MM-ddTHH:mm:ss.fffffffZ
。仅针对查询调整它并不足以满足所有情况。后来遇到了另一个类似的问题,如果不更改日期的存储方式,该问题也无法解决。 3 毫秒的位置对于许多应用程序来说可能就足够了,因为 JavaScript 将在 3 毫秒点处中断。但查询和写入都必须保持一致。微软自己似乎推荐这种格式yyyy-MM-ddTHH:mm:ss.fffffffZ
用于在cosmosdb中存储日期。