【发布时间】:2015-09-06 19:23:47
【问题描述】:
我有一个解决方案,问题是为什么会发生这种情况以及这是否是一个好的解决方案。 背景: 在 Azure DocumentDb 中,我有一个托管哈希将一个数据库分区为一个集合。 CLR 对象继承自 Document 类。我已将 JsonProperty-attribute 放在所有属性上。
不起作用的查询是这个:
var a = _client.CreateDocumentQuery<T>(_database.SelfLink)
.Where(d => d.Id == id)
.AsEnumerable()
.FirstOrDefault();
它总是返回 null (并且文档在那里,我在门户中看到它)。我现在浪费了这么多时间,我能做的就是:
var a = _client.CreateDocumentQuery<Document>(_database.SelfLink, "SELECT * FROM c")
.AsEnumerable().Where(t => t.Id == id)
.FirstOrDefault();
var obj = JsonConvert.SerializeObject(b);
T parsed = JsonConvert.DeserializeObject<T>(obj);
这不是有多可怕吗? 有谁知道为什么框架没有为我反序列化它,以及为什么它在第一个示例中找不到任何东西?
更新:
实际上,上面的“解决方案”并没有反序列化所有属性..
我有一个属性 Dictionary<Guid,Dictionary<string, string>> 不会反序列化到 CLR 属性中。根据智能感知,该对象属于 CLR 类型,但它有很多基类信息。虽然它似乎嵌套在永恒中。无法真正看到类型是什么,但 6 级(我认为它是 Resource 基类)我找到了一个私有 _propertybag,其中所有属性为 JTokens/JProperties(老实说,我不知道如何判断它们是哪一个) .
所以,那里有 json 数据,而我需要的数据在实际对象中,它只是没有绑定到属性。
我尝试在 Resource 类上使用 .SetProperty() 方法,并且确实有效。但这应该在从 DocumentClient 获取时进行反序列化和绑定,不是吗?
我在这里做错了什么?
2 个月后:
我再次对此进行了调查,结果发现,对于我的代码中的一个地方,上述可怕的解决方法仍然是唯一可以获取我的文档的方法。原因可以在链条的早期找到。该方法的参数是Expression<Func<TEntity,bool>>。
我的调用链是
public T CreateIfNotExists<T>(Guid id) where T : IBaseDocument
{
var id = ProduceDocId(typeof(T), id);
var result = _repository.GetSingle<T>(r => r.Id == id);
...
}
然后
public T GetSingle<T>(Expression<Func<T, bool>> predicate) where T : IBaseDocument
{
... // error handling ommitted
T res = _client.CreateDocumentQuery<T>(_database.SelfLink)
.Where(predicate)
.AsEnumerable()
.FirstOrDefault();
return res;
}
参数“谓词”将评估为匿名方法闭包,即在调试器中显示为“c__DisplayClass2”(explanation for name by Eric Lippert)。 像这样:
{s => (Convert(s).Id == value(FooNameSpace.BarClass+<>c__DisplayClass2`1[FooNameSpace.FooClass]).someId)}
documentdb 没有正确评估它,它总是返回 null。 如果我采用匿名方法闭包计算的实际 id 并改为传递,这会给我文档。
【问题讨论】:
标签: c# .net azure deserialization azure-cosmosdb