使用Cosmonaut比较CosmosDB SQL Api中的DateTime.Date

时间:2019-06-05 12:52:09

标签: c# azure-cosmosdb

使用SQL Api在CosmosDB中遇到了一个非常特殊的问题。

我基本上有一个具有CreatedAt字段的实体,该字段以iso格式存储,例如:

{
    "CreatedAt": "2019-06-05T10:55:19.3265682Z"
}

它位于建模为DateTime的实体上:

public class MyEntity {

    DateTime CreatedAt {get;set;} = DateTime.UtcNow;

}

如果我尝试与今天进行简单比较,它只会检索0个值:

_store.Query().Where(x => x.CreatedAt.Date == DateTime.UtcNow).ToListAsync();

我尝试过:

var test = await _store.Query().FirstOrDefaultAsync(); // 1 item

var f = test.CreatedAt.Date == DateTime.UtcNow.Date; // True

var offers = await _store.Query().Where(x => x.CreatedAt.Date == DateTime.UtcNow.Date ).ToListAsync(); // 0 results

在我看来,Linq子句的计算结果为非iso格式,尽管这很奇怪,因为Json.Net序列化程序默认为ISO标准,这是Cosmos中保存的。

创建的SQL是:

{"query":"SELECT VALUE root FROM root WHERE ((root[\"CosmosEntityName\"] = \"offers\") AND (root[\"CreatedAt\"][\"Date\"] = \"2019-06-05T00:00:00Z\")) "}

从解析的角度来看,这看起来很正确,但是可以肯定它将x.CreatedAt.Date转换为嵌套属性,尤其是因为它试图以[“ CreatedAt”] [“ Date”]的形式访问它。

如果我省略了.Date,显然它会与2019-06-05T12:26:43.0025189Z = 2019-06-05T00:00:00Z之类的东西进行比较,这当然不是事实。

在模拟器中运行该查询还会产生没有意义的结果:

SELECT root["CreatedAt"]["Date"]  FROM root WHERE root["CosmosEntityName"] = "offers" 
->
[
    {},
    {},
    {},
    {},
    {},
...
]

看文档,有一个看起来像这样的例子:

IQueryable<Order> orders = client.CreateDocumentQuery<Order>("/dbs/orderdb/colls/orders")
    .Where(o => o.ShipDate >= DateTime.UtcNow.AddDays(-3));

这促使我思考是否应该忽略比较实际日期(或将它们存储在其各自的属性中?),而仅使用>=<=来包装实际时间戳,只是看起来很傻。

1 个答案:

答案 0 :(得分:0)

使用CreatedAt.Date使LINQ to SQL转换程序认为它是类内的嵌套对象。

如果您只需要在CreatedAt中正确地进行日期比较,那么最简单的方法是将CreatedAt存为DateTime,并将CreateAtDateCreatedAt DateTime相同,并且“时间”部分设置为0。

然后只需:

var offers = await _store.Query().Where(x => x.CreatedAtDate == DateTime.UtcNow.Date ).ToListAsync();