2016-02-18 22 views
5

posso interrogare un singolo documento dalla Azure DocumentDB in questo modo:documento Leggi Azure DocumentDB che potrebbero non esistere

var response = await client.ReadDocumentAsync(documentUri); 

Se il documento non esiste, questo sarà lanciare un DocumentClientException. Nel mio programma ho una situazione in cui il documento può o non può esistere. Esiste un modo per interrogare il documento senza utilizzare try-catch e senza effettuare due round trip sul server, prima per richiedere il documento e il secondo per recuperare il documento se esiste?

risposta

4

Si sta specificamente interrogando per un determinato documento e ReadDocumentAsync si getterà quello DocumentClientException quando non riesce a trovare il documento specifico (restituendo un 404 nel codice di stato). Questo è documentato here. Osservando l'eccezione (e vedendo che è un 404), non avresti bisogno di due viaggi di andata e ritorno.

Per ovviare a questa eccezione, è necessario creare una query anziché una lettura discreta, utilizzando CreateDocumentQuery(). Quindi, otterrai semplicemente un set di risultati che puoi enumerare (anche se il set di risultati è vuoto). Ad esempio:

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()) 
{ 
    // ... 
} 

Con questo approccio, non riceverai alcuna risposta. Nel tuo caso specifico, dove aggiungerai una clausola WHERE per interrogare un documento specifico tramite il suo id, o otterrai zero risultati o un risultato.

+0

Probabilmente vorresti comunque gestire le eccezioni, quindi questa sembra essere un'alternativa molto migliore di una verifica preliminare dell'esistenza, IMHO. –

+0

Gestire l'eccezione è l'approccio migliore, poiché nella maggior parte dei casi l'esecuzione di query da parte di Id utilizza meno RU di una query che trova solo un risultato per il suo ID. –

+1

È strano che dobbiamo ricorrere alle eccezioni. Comunicare tramite le eccezioni di solito diventa costoso in quanto le eccezioni tendono a pesare e di solito è un no-no. In questo caso perché questo va su TCP, il server deve restituire un codice e in questo caso è un 404. Quindi diventa un po 'un male necessario. Mi piace l'idea di usare una query per vedere se ci sono risultati. Ciò non comporterebbe un'eccezione. Anche il codice sembra strano con una cattura di prova. – FabianVal

6

Purtroppo non c'è altro modo, o si gestire l'eccezione o si fanno 2 chiamate, se si sceglie la seconda strada, qui è un modo prestazioni-driven di controllo per l'esistenza del documento:

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 
} 

Il il client dovrebbe essere condiviso tra tutti i metodi di accesso al database, ma l'ho creato lì per avere un esempio auto-sufficiente.

Il new FeedOptions() {MaxItemCount = 1} assicurerà che la query sarà ottimizzata per 1 risultato (non abbiamo davvero bisogno di più).

Il Select(x=>x.Id) si accerterà che nessun altro dato venga restituito, se non lo si specifica e il documento esiste, interrogherà e restituirà tutte le sue informazioni.

Problemi correlati