CreateDocumentQuery不绑定到CLR对象

时间:2015-09-06 19:23:47

标签: c# .net azure deserialization azure-cosmosdb

我有一个解决方案,问题是为什么会发生这种情况,如果这是一个很好的解决方案。 背景: 在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,而是传入,则会给我文档。

2 个答案:

答案 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