2016-02-18 4 views
5

ich ein einzelnes Dokument aus dem Azure DocumentDB wie folgt abfragen:lesen Azure DocumentDB Dokument, das nicht existieren könnte

var response = await client.ReadDocumentAsync(documentUri); 

Wenn das Dokument nicht existiert, wird dies eine DocumentClientException werfen. In meinem Programm habe ich eine Situation, in der das Dokument existiert oder nicht. Gibt es eine Möglichkeit, das Dokument abzufragen, ohne try-catch zu verwenden, und ohne zwei Rundreisen zum Server zu machen, um das Dokument anzufragen und das Dokument dann wiederzufinden, falls es existiert?

Antwort

4

Sie suchen speziell nach einem bestimmten Dokument, und ReadDocumentAsync wird das DocumentClientException werfen, wenn es das bestimmte Dokument nicht finden kann (eine 404 im Statuscode zurückgibt). Dies ist dokumentiert here. Wenn Sie die Ausnahme abfangen (und sehen, dass es sich um einen 404 handelt), würden Sie nicht zwei Rundreisen benötigen.

Um diese Ausnahme umgehen zu können, müssen Sie anstelle von diskretem Lesen eine Abfrage durchführen, indem Sie CreateDocumentQuery() verwenden. Dann erhalten Sie einfach eine Ergebnismenge, durch die Sie auflisten können (auch wenn diese Ergebnismenge leer ist). Zum Beispiel:

var collLink = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId); 
var querySpec = new SqlQuerySpec { <querytext> }; 

var itr = client.CreateDocumentQuery(collLink, querySpec).AsDocumentQuery(); 
var response = await itr.ExecuteNextAsync<Document>(); 

foreach (var doc in response.AsEnumerable()) 
{ 
    // ... 
} 

Mit diesem Ansatz werden Sie nur keine Antworten erhalten. In Ihrem speziellen Fall, in dem Sie eine WHERE-Klausel hinzufügen, um ein bestimmtes Dokument anhand seiner ID abzufragen, erhalten Sie entweder null Ergebnisse oder ein Ergebnis.

+0

Sie würden wahrscheinlich sowieso mit Ausnahmen umgehen wollen, also scheint dies eine viel bessere Alternative zu sein als eine Preflight-Prüfung auf Existenz, IMHO. –

+0

Die Behandlung der Ausnahme ist der bessere Ansatz, da in den meisten Fällen die Abfrage nach Id weniger RUs als eine Abfrage verwendet, die nur ein Ergebnis anhand ihrer ID findet. –

+1

Es ist seltsam, dass wir auf Ausnahmen zurückgreifen müssen. Die Kommunikation über Ausnahmen wird in der Regel teuer, da Ausnahmen zu schwerwiegend sind und in der Regel ein Nein-Nein sind. In diesem Fall, weil dies über TCP geht, muss der Server einen Code zurückgeben und in diesem Fall ist es ein 404. So wird es ein bisschen ein notwendiges Übel. Ich mag die Idee, stattdessen eine Abfrage zu verwenden, um zu sehen, ob es Ergebnisse gibt. Das würde nicht zu einer Ausnahme führen. Der Code sieht auch komisch aus mit einem Versuch zu fangen. – FabianVal

6

Leider gibt es keine andere Möglichkeit, entweder Sie behandeln die Ausnahme oder Sie machen zwei Anrufe, wenn Sie den zweiten Weg wählen, hier ist eine leistungsorientierte Art und Weise für die Dokumenten Existenz Überprüfung:

public bool ExistsDocument(string id) 
{ 
    var client = new DocumentClient(DatabaseUri, DatabaseKey); 
    var collectionUri = UriFactory.CreateDocumentCollectionUri("dbName", "collectioName"); 
    var query = client.CreateDocumentQuery<Microsoft.Azure.Documents.Document>(collectionUri, new FeedOptions() { MaxItemCount = 1 }); 
    return query.Where(x => x.Id == id).Select(x=>x.Id).AsEnumerable().Any(); //using Linq 
} 

Die Der Client sollte unter all Ihren DB-Access-Methoden geteilt werden, aber ich habe ihn dort angelegt, um ein Auto-sufficient-Beispiel zu haben.

Die new FeedOptions() {MaxItemCount = 1} wird sicherstellen, dass die Abfrage für 1 Ergebnis optimiert wird (wir brauchen nicht wirklich mehr).

Die Select(x=>x.Id) wird sicherstellen, dass keine anderen Daten zurückgegeben werden, wenn Sie es nicht angeben und das Dokument existiert, wird es abfragen und alle Informationen zurückgeben.

Verwandte Themen