Guy Assaf
Guy Assaf

Reputation: 991

Azure DocumentDB, CreateDocumentQuery in .NET SDK does not return the "id" and "_self"

When using the next code in .NET:

var q = DocumentDBHelper.Client.CreateDocumentQuery<WishListUserItems>(DocumentDBHelper.CollUri(eCollection.WishList),
                    "SELECT c.UserId, c.Items FROM c JOIN items IN c.Items);

            var lst = q.ToList();

The objects return in the "lst" does not have the service fields (_self, id, _rid)

although the object "WishListUserItems" inherit from "Document". even tried to add properties to "WishListUserItems", like "id", "_self".

Upvotes: 0

Views: 307

Answers (1)

flytzen
flytzen

Reputation: 7448

It looks like the problem is that you are running custom SQL, rather than just retrieving a document.

SELECT c.UserId, c.Items FROM c JOIN items IN c.Items

means that DocumentDb no longer deals with documents as such, it is projecting data and just returning a data set, not documents, meaning it doesn't make any sense for DocumentDb to try to return an id or _self.
The returned data is de-serialised into whatever type you asked for. Note that because you are using custom SQL, you are not getting the whole document so you should not be tempted to save this instance back to DocumentDb.

That said, if you do want to get the id and _self so you can later retrieve and update the underlying documents, you should be able to just include those in your SQL statement and add corresponding fields on your model class.

Something like

SELECT c.UserId, c.id, c._self, c.Items FROM c JOIN items IN c.Items)

(not tested).

More generically for documents

When you just retrieve actual documents generally, you may also lament the lack of "id" and "_self". We implemented a DocumentBase class to help with this, something like this;

public abstract class DocumentBase
{

    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "_etag")]
    public string ETag { get; set; }

    [JsonProperty(PropertyName = "_self")]
    public string SelfIdentifier { get; set; }
}

The ETag is a bit more complicated to use correctly as you need to manually update it when you save the record back, but can be used to implement some optimistic concurrency protection.

Upvotes: 1

Related Questions