我有一个解决方案,问题是为什么会发生这种情况,如果这是一个很好的解决方案。 背景: 在Azure DocumentDb中,我有一个托管哈希,用一个集合对数据库进行分区。 CLR对象继承自Document类。我已将JsonProperty属性放在所有属性上。
不起作用的查询就是这个:
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);
那有多糟糕? 有谁知道为什么框架不会为我反序列化,以及为什么它没有找到第一个例子的任何内容?
更新
实际上,以上&#34;解决方案&#34;没有反序列化所有属性..
我有一个属性Dictionary<Guid,Dictionary<string, string>>
,它不会反序列化为CLR属性。根据intellisense,对象属于CLR类型,但它有很多基类信息。它似乎嵌套在永恒中。难道不能真正看到类型是什么但只有6级(我认为它是资源基类)我找到了一个私有_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;
}
参数&#39;谓词&#39;将评估一个匿名的方法闭包,即在调试器中显示&#39; c__DisplayClass2&#39; (explanation for name by Eric Lippert)。 像这样:
{s => (Convert(s).Id == value(FooNameSpace.BarClass+<>c__DisplayClass2`1[FooNameSpace.FooClass]).someId)}
documentdb没有正确评估它,它将始终返回null。 如果我采用匿名方法闭包计算的实际id,而是传入,则会给我文档。
答案 0 :(得分:2)
解决!非常简单的回答,这完全归功于我的无知和缺乏正确的研究工作(因为男人,我付出了努力......)。
未来文档上的属性设置器无法访问,即私有或受保护不正常。
那就是它。
2个月后: 实际上,那不是它。请参阅原始问题的最后一部分。
答案 1 :(得分:0)
您不需要反序列化从DocumentDB读取Document。 像这样的函数应该为你做(这个函数中的类名与你的不同):
public List<Candidate> GetCandidateById(int candidateId)
{
var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey);
Database database = client.CreateDatabaseQuery().Where(db => db.Id == DatabaseName).AsEnumerable().FirstOrDefault();
DocumentCollection documentCollection = client.CreateDocumentCollectionQuery(database.CollectionsLink).Where(db => db.Id == DocumentCollectionName).AsEnumerable().FirstOrDefault();
return client.CreateDocumentQuery<Candidate>(documentCollection.DocumentsLink).Where(m => m.CandidateId == candidateId).Select(m => m).ToList();
}
我在这里发布了一个DocumentDB示例:
http://koukia.ca/post/azure-documentdb-vs-sql-azure,-a-performance-comparison