I have one solution, the question is why this happens and if this is a good solution. Background: In Azure DocumentDb I have a managed hash partitioned a db with one collection. The CLR objects inherit from the Document class. I have put JsonProperty-attribute on all properties.
The query that doesn't work is this one:
var a = _client.CreateDocumentQuery<T>(_database.SelfLink)
.Where(d => d.Id == id)
.AsEnumerable()
.FirstOrDefault();
It would always return null (and the doc is there, I see it in the portal). I've been wasting so much time now, and all that I could get working was this:
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);
How awful isn't that? Does anyone know why the framework isn't deserializing this for me, and why it doesn't find anything with the first example?
Update:
Actually, that above "solution" doesn't deserialize all properties..
I have a property Dictionary<Guid,Dictionary<string, string>>
that does not deserialize into the CLR property. The object is of the CLR type according to intellisense, but it has a lot of base class info. It seems to be nested in eternity though. Can't really see what the type is but 6 levels up (I think it's the Resource base class) I find a private _propertybag with all the properties as JTokens/JProperties (I honestly don't know how to tell which one they are).
So, there's json data there, and the data I need is in the actual object, it just didn't bind to the property.
I've tried to use the .SetProperty() method on the Resource class, and that does work. But this should be deserialized and bound when getting from the DocumentClient, no?
What am I doing wrong here?
2 months later:
I was looking into this again, and it turns out that for one place in my code the above horrific workaround was still the only thing that could get my document. The reason though was to be found earlier in the chain. The parameter for that method was Expression<Func<TEntity,bool>>
.
My chain for calling this was
public T CreateIfNotExists<T>(Guid id) where T : IBaseDocument
{
var id = ProduceDocId(typeof(T), id);
var result = _repository.GetSingle<T>(r => r.Id == id);
...
}
and then
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;
}
The parameter 'predicate' would evaluate to an anonymous method closure, i.e. showing up in the debugger with 'c__DisplayClass2' (explanation for name by Eric Lippert). Like so:
{s => (Convert(s).Id == value(FooNameSpace.BarClass+<>c__DisplayClass2`1[FooNameSpace.FooClass]).someId)}
This isn't evaluated correctly by documentdb, and it will always return null. If I take the actual id that the anonymous method closure evaluates to, and pass in instead, that gives me the document.