使用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));
这促使我思考是否应该忽略比较实际日期(或将它们存储在其各自的属性中?),而仅使用>=
和<=
来包装实际时间戳,只是看起来很傻。
答案 0 :(得分:0)
使用CreatedAt.Date
使LINQ to SQL转换程序认为它是类内的嵌套对象。
如果您只需要在CreatedAt
中正确地进行日期比较,那么最简单的方法是将CreatedAt
存为DateTime
,并将CreateAtDate
与CreatedAt
DateTime
相同,并且“时间”部分设置为0。
然后只需:
var offers = await _store.Query().Where(x => x.CreatedAtDate == DateTime.UtcNow.Date ).ToListAsync();