Eseguire la migrazione dell'applicazione per usare Azure Cosmos DB .NET SDK v3

SI APPLICA A: NoSQL

Importante

Per informazioni su Azure Cosmos DB .NET SDK v3, vedere le note sulla versione, il repository GitHub .NET, i suggerimenti sulle prestazioni per .NET SDK v3 e la guida alla risoluzione dei problemi.

Questo articolo illustra alcune considerazioni sull'aggiornamento dell'applicazione .NET esistente alla versione più recente di Azure Cosmos DB .NET SDK v3 per l'API per NoSQL. Azure Cosmos DB .NET SDK v3 corrisponde allo spazio dei nomi Microsoft.Azure.Azure Cosmos DB. È possibile usare le informazioni fornite in questo documento se si esegue la migrazione dell'applicazione da uno degli SDK .NET di Azure Cosmos DB seguenti:

  • Azure Cosmos DB .NET Framework SDK v2 per API per NoSQL
  • Azure Cosmos DB .NET Core SDK v2 per API per NoSQL

Le istruzioni in questo articolo consentono anche di eseguire la migrazione delle librerie esterne seguenti che fanno ora parte di Azure Cosmos DB .NET SDK v3 per API per NoSQL:

  • Libreria del processore dei feed di modifiche .NET 2.0
  • Libreria dell'executor bulk .NET 1.1 o versione successiva

Novità di .NET V3 SDK

L'SDK v3 contiene numerosi miglioramenti dell'usabilità e delle prestazioni, tra cui:

  • Denominazione intuitiva del modello di programmazione
  • .NET Standard 2.0+
  • Miglioramento delle prestazioni tramite il supporto dell'API di flusso
  • Gerarchia Fluent che sostituisce la necessità di factory URI
  • Supporto predefinito per la libreria del processore dei feed di modifiche
  • Supporto predefinito per le operazioni bulk
  • API fittizie per un test unità più semplice
  • Supporto per batch transazionale e Blazor
  • Serializzatori collegabili
  • Dimensionare i contenitori di scalabilità automatica e non partizionati

** L'SDK è destinato a .NET Standard 2.0 che unifica gli SDK .NET Framework e .NET Core esistenti in un singolo SDK .NET. È possibile usare .NET SDK in qualsiasi piattaforma che implementa .NET Standard 2.0, incluse le applicazioni .NET Framework 4.6.1+ e .NET Core 2.0+.

La maggior parte delle reti, la logica di ripetizione dei tentativi e i livelli inferiori dell'SDK rimangono in gran parte invariati.

Azure Cosmos DB .NET SDK v3 è ora open source. Sono disponibili tutte le richieste pull e verranno registrati i problemi e il feedback di rilevamento su GitHub. Si lavorerà su tutte le funzionalità che miglioreranno l'esperienza dei clienti.

Perché eseguire la migrazione a .NET v3 SDK

Oltre ai numerosi miglioramenti per l'usabilità e le prestazioni, i nuovi investimenti di funzionalità effettuati nell'SDK più recente non verranno trasferiti alle versioni precedenti. L'SDK v2 è attualmente in modalità di manutenzione. Per un'esperienza di sviluppo ottimale, è consigliabile iniziare sempre con la versione più recente supportata di SDK.

Modifiche principali del nome da SDK v2 a v3 SDK

Le modifiche al nome seguenti sono state applicate in .NET 3.0 SDK per allinearsi alle convenzioni di denominazione api per l'API per NoSQL:

  • DocumentClient viene rinominata CosmosClient
  • Collection viene rinominata Container
  • Document viene rinominata Item

Tutti gli oggetti risorsa vengono rinominati con proprietà aggiuntive, che includono il nome della risorsa per maggiore chiarezza.

Di seguito sono riportate alcune delle modifiche apportate al nome della classe principale:

SDK .NET v2 SDK .NET v3
Microsoft.Azure.Documents.Client.DocumentClient Microsoft.Azure.Cosmos.CosmosClient
Microsoft.Azure.Documents.Client.ConnectionPolicy Microsoft.Azure.Cosmos.CosmosClientOptions
Microsoft.Azure.Documents.Client.DocumentClientException Microsoft.Azure.Cosmos.CosmosException
Microsoft.Azure.Documents.Client.Database Microsoft.Azure.Cosmos.DatabaseProperties
Microsoft.Azure.Documents.Client.DocumentCollection Microsoft.Azure.Cosmos.ContainerProperties
Microsoft.Azure.Documents.Client.RequestOptions Microsoft.Azure.Cosmos.ItemRequestOptions
Microsoft.Azure.Documents.Client.FeedOptions Microsoft.Azure.Cosmos.QueryRequestOptions
Microsoft.Azure.Documents.Client.StoredProcedure Microsoft.Azure.Cosmos.StoredProcedureProperties
Microsoft.Azure.Documents.Client.Trigger Microsoft.Azure.Cosmos.TriggerProperties
Microsoft.Azure.Documents.SqlQuerySpec Microsoft.Azure.Cosmos.QueryDefinition

Classi sostituite in .NET v3 SDK

Le classi seguenti sono state sostituite nell'SDK 3.0:

  • Microsoft.Azure.Documents.UriFactory

La classe Microsoft.Azure.Documents.UriFactory è stata sostituita dalla progettazione Fluent.

Container container = client.GetContainer(databaseName,containerName);
ItemResponse<SalesOrder> response = await this._container.CreateItemAsync(
        salesOrder,
        new PartitionKey(salesOrder.AccountNumber));

  • Microsoft.Azure.Documents.Document

Poiché .NET v3 SDK consente agli utenti di configurare un motore di serializzazione personalizzato, non esiste alcuna sostituzione diretta per il tipo Document. Quando si usa Newtonsoft.Json (motore di serializzazione predefinito), è possibile usare JObject per ottenere la stessa funzionalità. Quando si usa un motore di serializzazione diverso, è possibile usare il tipo di documento JSON di base, ad esempio JsonDocument per System.Text.Json. È consigliabile usare un tipo C# che riflette lo schema degli elementi anziché basarsi su tipi generici.

  • Microsoft.Azure.Documents.Resource

Non esiste alcuna sostituzione diretta per Resource, nei casi in cui è stata usata per i documenti, seguire le indicazioni per Document.

  • Microsoft.Azure.Documents.AccessCondition

IfNoneMatch o IfMatch sono ora disponibili direttamente in Microsoft.Azure.Cosmos.ItemRequestOptions.

Modifiche alla generazione di ID elemento

L'ID elemento non viene più popolato automaticamente in .NET v3 SDK. Pertanto, l'ID elemento deve includere in modo specifico un ID generato. Visualizzare l'esempio seguente:

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

Modifica del comportamento predefinito per la modalità di connessione

L'SDK v3 ora usa per impostazione predefinita la modalità di connessione Direct + TCP rispetto all'SDK v2 precedente, che per impostazione predefinita corrisponde alle modalità gateway e connessioni HTTPS. Questa modifica offre prestazioni e scalabilità migliorate.

Modifiche a FeedOptions (QueryRequestOptions in v3.0 SDK)

La classe FeedOptions in SDK v2 è stata ora rinominata QueryRequestOptions nell'SDK v3 e all'interno della classe, diverse proprietà hanno apportato modifiche al nome e/o al valore predefinito o sono state rimosse completamente.

SDK .NET v2 SDK .NET v3
FeedOptions.MaxDegreeOfParallelism QueryRequestOptions.MaxConcurrency: il valore predefinito e il comportamento associato rimangono invariati, le operazioni eseguite sul lato client durante l'esecuzione di query parallele verranno eseguite in modo seriale senza parallelismo.
FeedOptions.PartitionKey QueryRequestOptions.PartitionKey: comportamento gestito.
FeedOptions.EnableCrossPartitionQuery Rimosso. Il comportamento predefinito in SDK 3.0 è che le query tra partizioni verranno eseguite senza la necessità di abilitare specificamente la proprietà.
FeedOptions.PopulateQueryMetrics Rimosso. È ora abilitata per impostazione predefinita e parte della diagnostica.
FeedOptions.RequestContinuation Rimosso. Viene ora alzato di livello ai metodi di query stessi.
FeedOptions.JsonSerializerSettings Rimosso. Per altre informazioni, vedere come personalizzare di serializzazione.
FeedOptions.PartitionKeyRangeId Rimosso. Lo stesso risultato può essere ottenuto usando FeedRange come input per il metodo di query.
FeedOptions.DisableRUPerMinuteUsage Rimosso.

Creazione di un client

.NET SDK v3 offre una classe fluent CosmosClientBuilder che sostituisce la necessità di SDK v2 URI Factory.

La progettazione Fluent compila internamente gli URL e consente di passare un singolo oggetto Container anziché DocumentClient, DatabaseName e DocumentCollection.

Nell'esempio seguente viene creato un nuovo CosmosClientBuilder con coerenza assoluta e un elenco di posizioni preferite:

CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder(
    accountEndpoint: "https://testcosmos.documents.azure.com:443/",
    authKeyOrResourceToken: "SuperSecretKey")
.WithConsistencyLevel(ConsistencyLevel.Strong)
.WithApplicationRegion(Regions.EastUS);
CosmosClient client = cosmosClientBuilder.Build();

Eccezioni

Se l'SDK v2 ha usato DocumentClientException per segnalare errori durante le operazioni, l'SDK v3 usa CosmosException, che espone StatusCode, Diagnostics e altre informazioni correlate alla risposta. Tutte le informazioni complete vengono serializzate quando viene usato ToString():

catch (CosmosException ex)
{
    HttpStatusCode statusCode = ex.StatusCode;
    CosmosDiagnostics diagnostics = ex.Diagnostics;
    // store diagnostics optionally with diagnostics.ToString();
    // or log the entire error details with ex.ToString();
}

Diagnostica

Se l'SDK v2 aveva la diagnostica solo diretta disponibile tramite la proprietà RequestDiagnosticsString, l'SDK v3 usa Diagnostics disponibile in tutte le risposte e le eccezioni, che sono più avanzate e non limitate alla modalità diretta. Includono non solo il tempo dedicato all'SDK per l'operazione, ma anche le aree in cui è stata contattata l'operazione:

try
{
    ItemResponse<MyItem> response = await container.ReadItemAsync<MyItem>(
                    partitionKey: new PartitionKey("MyPartitionKey"),
                    id: "MyId");
    
    TimeSpan elapsedTime = response.Diagnostics.GetElapsedTime();
    if (elapsedTime > somePreDefinedThreshold)
    {
        // log response.Diagnostics.ToString();
        IReadOnlyList<(string region, Uri uri)> regions = response.Diagnostics.GetContactedRegions();
    }
}
catch (CosmosException cosmosException) {
    string diagnostics = cosmosException.Diagnostics.ToString();
    
    TimeSpan elapsedTime = cosmosException.Diagnostics.GetElapsedTime();
    
    IReadOnlyList<(string region, Uri uri)> regions = cosmosException.Diagnostics.GetContactedRegions();
    
    // log cosmosException.ToString()
}

ConnectionPolicy

Alcune impostazioni in ConnectionPolicy sono state rinominate o sostituite da CosmosClientOptions:

SDK .NET v2 SDK .NET v3
EnableEndpointDiscovery LimitToEndpoint: il valore viene ora invertito, se EnableEndpointDiscovery è stato impostato su true, LimitToEndpoint deve essere impostato su false. Prima di usare questa impostazione, è necessario comprendere come influisce sul client.
ConnectionProtocol Rimosso. Il protocollo è associato alla modalità, ovvero Gateway (HTTPS) o Direct (TCP). La modalità diretta con il protocollo HTTPS non è più supportata in V3 SDK e si consiglia di usare il protocollo TCP.
MediaRequestTimeout Rimosso. Gli allegati non sono più supportati.
SetCurrentLocation CosmosClientOptions.ApplicationRegion può essere usato per ottenere lo stesso effetto.
PreferredLocations CosmosClientOptions.ApplicationPreferredRegions può essere usato per ottenere lo stesso effetto.
UserAgentSuffix CosmosClientBuilder.ApplicationName può essere usato per ottenere lo stesso effetto.
UseMultipleWriteLocations Rimosso. L'SDK rileva automaticamente se l'account supporta più endpoint di scrittura.

Criterio di indicizzazione

Nei criteri di indicizzazione non è possibile configurare queste proprietà. Se non specificato, queste proprietà avranno sempre i valori seguenti:

Nome proprietà nuovo valore (non configurabile)
Kind range
dataType String e Number

Vedere questa sezione per consultare esempi di criteri di indicizzazione per includere ed escludere i percorsi. A causa di miglioramenti nel motore di query, la configurazione di queste proprietà, anche se si usa una versione precedente dell'SDK, non ha alcun impatto sulle prestazioni.

Token di sessione

Se l'SDK v2 ha esposto il token di sessione di una risposta come ResourceResponse.SessionToken per i casi in cui è necessaria l'acquisizione del token di sessione, poiché il token di sessione è un'intestazione, l'SDK v3 espone tale valore nella proprietà Headers.Session di qualsiasi risposta.

Timestamp:

Quando l'SDK v2 ha esposto il timestamp di un documento tramite la proprietà Timestamp, poiché Document non è più disponibile, gli utenti possono eseguire il mapping della _tsproprietà di sistema a una proprietà nel modello.

OpenAsync

Per i casi d'uso in cui OpenAsync() è stato usato per riscaldare il client SDK v2, CreateAndInitializeAsync può essere usato sia per creare sia per avviare un client SDK v3.

Uso delle API del processore del feed di modifiche direttamente dall'SDK v3

L'SDK v3 include il supporto predefinito per le API processore dei feed di modifiche, consentendo di usare lo stesso SDK per la compilazione dell'applicazione e l'implementazione del processore del feed di modifiche. In precedenza era necessario usare una libreria separata del processore dei feed di modifiche.

Per altre informazioni, vedere come eseguire la migrazione dalla libreria del processore dei feed di modifiche ad Azure Cosmos DB .NET v3 SDK

Query del feed di modifiche

L'esecuzione di query sui feed di modifiche nell'SDK v3 viene considerata l'uso del modello pull del feed di modifiche. Seguire questa tabella per eseguire la migrazione della configurazione:

SDK .NET v2 SDK .NET v3
ChangeFeedOptions.PartitionKeyRangeId FeedRange: per ottenere il parallelismo durante la lettura del feed di modifiche è possibile usare feedRanges. Non è più un parametro obbligatorio, è possibile leggere il feed di modifiche per un intero contenitore facilmente.
ChangeFeedOptions.PartitionKey FeedRange.FromPartitionKey: è possibile usare un feedRange che rappresenta la chiave di partizione desiderata per leggere il feed di modifiche per il valore della chiave di partizione.
ChangeFeedOptions.RequestContinuation ChangeFeedStartFrom.Continuation: l'iteratore del feed di modifiche può essere arrestato e ripreso in qualsiasi momento salvando la continuazione e usandola durante la creazione di un nuovo iteratore.
ChangeFeedOptions.StartTime ChangeFeedStartFrom.Time
ChangeFeedOptions.StartFromBeginning ChangeFeedStartFrom.Beginning
ChangeFeedOptions.MaxItemCount ChangeFeedRequestOptions.PageSizeHint: l'iteratore del feed di modifiche può essere arrestato e ripreso in qualsiasi momento salvando la continuazione e usandola durante la creazione di un nuovo iteratore.
IDocumentQuery.HasMoreResults response.StatusCode == HttpStatusCode.NotModified: il feed di modifiche è concettualmente infinito, quindi potrebbero esserci sempre più risultati. Quando una risposta contiene il codice di stato HttpStatusCode.NotModified, significa che non sono state apportate nuove modifiche da leggere in questo momento. È possibile usarlo per arrestare e salvare la continuazione o per sospendere o attendere temporaneamente e quindi chiamare di nuovo ReadNextAsync per testare le nuove modifiche.
Suddivisione della gestione Non è più necessario per gli utenti gestire le eccezioni suddivise durante la lettura del feed di modifiche, le divisioni verranno gestite in modo trasparente senza la necessità di interazione dell'utente.

Uso della libreria bulk executor direttamente dall'SDK V3

L'SDK v3 include il supporto predefinito per la libreria dell'executor bulk, che consente di usare lo stesso SDK per la compilazione dell'applicazione e l'esecuzione di operazioni bulk. In precedenza era necessario usare una libreria di executor bulk separata.

Per altre informazioni, vedere come eseguire la migrazione dalla libreria dell'executor bulk al supporto in blocco in Azure Cosmos DB .NET V3 SDK

Personalizzare la serializzazione

.NET V2 SDK consente di impostare JsonSerializerSettings in RequestOptions a livello operativo per deserializzare il documento del risultato:

// .NET V2 SDK
var result = await container.ReplaceDocumentAsync(document, new RequestOptions { JsonSerializerSettings = customSerializerSettings })

.NET SDK v3 fornisce un'interfaccia serializzatore per personalizzare completamente il motore di serializzazione o più opzioni di serializzazione generiche come parte della costruzione client.

La personalizzazione della serializzazione a livello di operazione può essere ottenuta tramite l'uso delle API stream:

// .NET V3 SDK
using(Response response = await this.container.ReplaceItemStreamAsync(stream, "itemId", new PartitionKey("itemPartitionKey"))
{

    using(Stream stream = response.ContentStream)
    {
        using (StreamReader streamReader = new StreamReader(stream))
        {
            // Read the stream and do dynamic deserialization based on type with a custom Serializer
        }
    }
}

Confronti tra frammenti di codice

Il frammento di codice seguente mostra le differenze nella modalità di creazione delle risorse tra gli SDK .NET v2 e v3:

Operazioni del database

Creazione di un database

// Create database with no shared provisioned throughput
DatabaseResponse databaseResponse = await client.CreateDatabaseIfNotExistsAsync(DatabaseName);
Database database = databaseResponse;
DatabaseProperties databaseProperties = databaseResponse;

// Create a database with a shared manual provisioned throughput
string databaseIdManual = new string(DatabaseName + "_SharedManualThroughput");
database = await client.CreateDatabaseIfNotExistsAsync(databaseIdManual, ThroughputProperties.CreateManualThroughput(400));

// Create a database with shared autoscale provisioned throughput
string databaseIdAutoscale = new string(DatabaseName + "_SharedAutoscaleThroughput");
database = await client.CreateDatabaseIfNotExistsAsync(databaseIdAutoscale, ThroughputProperties.CreateAutoscaleThroughput(4000));

Leggere un database in base all'ID

// Read a database
Console.WriteLine($"{Environment.NewLine} Read database resource: {DatabaseName}");
database = client.GetDatabase(DatabaseName);
Console.WriteLine($"{Environment.NewLine} database { database.Id.ToString()}");

// Read all databases
string findQueryText = "SELECT * FROM c";
using (FeedIterator<DatabaseProperties> feedIterator = client.GetDatabaseQueryIterator<DatabaseProperties>(findQueryText))
{
    while (feedIterator.HasMoreResults)
    {
        FeedResponse<DatabaseProperties> databaseResponses = await feedIterator.ReadNextAsync();
        foreach (DatabaseProperties _database in databaseResponses)
        {
            Console.WriteLine($"{ Environment.NewLine} database {_database.Id.ToString()}");
        }
    }
}

Eliminare un database

// Delete a database
await client.GetDatabase(DatabaseName).DeleteAsync();
Console.WriteLine($"{ Environment.NewLine} database {DatabaseName} deleted.");

// Delete all databases in an account
string deleteQueryText = "SELECT * FROM c";
using (FeedIterator<DatabaseProperties> feedIterator = client.GetDatabaseQueryIterator<DatabaseProperties>(deleteQueryText))
{
    while (feedIterator.HasMoreResults)
    {
        FeedResponse<DatabaseProperties> databaseResponses = await feedIterator.ReadNextAsync();
        foreach (DatabaseProperties _database in databaseResponses)
        {
            await client.GetDatabase(_database.Id).DeleteAsync();
            Console.WriteLine($"{ Environment.NewLine} database {_database.Id} deleted");
        }
    }
}

Operazioni del contenitore

Creare un contenitore (scalabilità automatica + durata con scadenza)

private static async Task CreateManualThroughputContainer(Database database)
{
    // Set throughput to the minimum value of 400 RU/s manually configured throughput
    string containerIdManual = ContainerName + "_Manual";
    ContainerResponse container = await database.CreateContainerIfNotExistsAsync(
        id: containerIdManual,
        partitionKeyPath: partitionKeyPath,
        throughput: 400);
}

// Create container with autoscale
private static async Task CreateAutoscaleThroughputContainer(Database database)
{
    string autoscaleContainerId = ContainerName + "_Autoscale";
    ContainerProperties containerProperties = new ContainerProperties(autoscaleContainerId, partitionKeyPath);

    Container container = await database.CreateContainerIfNotExistsAsync(
        containerProperties: containerProperties,
        throughputProperties: ThroughputProperties.CreateAutoscaleThroughput(autoscaleMaxThroughput: 4000);
}

// Create a container with TTL Expiration
private static async Task CreateContainerWithTtlExpiration(Database database)
{
    string containerIdManualwithTTL = ContainerName + "_ManualTTL";

    ContainerProperties properties = new ContainerProperties
        (id: containerIdManualwithTTL,
        partitionKeyPath: partitionKeyPath);

    properties.DefaultTimeToLive = (int)TimeSpan.FromDays(1).TotalSeconds; //expire in 1 day

    ContainerResponse containerResponse = await database.CreateContainerIfNotExistsAsync(containerProperties: properties);
    ContainerProperties returnedProperties = containerResponse;
}

Leggere le proprietà del contenitore

private static async Task ReadContainerProperties(Database database)
{
    string containerIdManual = ContainerName + "_Manual";
    Container container = database.GetContainer(containerIdManual);
    ContainerProperties containerProperties = await container.ReadContainerAsync();
}

Eliminare un contenitore

private static async Task DeleteContainers(Database database)
{
    string containerIdManual = ContainerName + "_Manual";

    // Delete a container
    await database.GetContainer(containerIdManual).DeleteContainerAsync();

    // Delete all CosmosContainer resources for a database
    using (FeedIterator<ContainerProperties> feedIterator = database.GetContainerQueryIterator<ContainerProperties>())
    {
        while (feedIterator.HasMoreResults)
        {
            foreach (ContainerProperties _container in await feedIterator.ReadNextAsync())
            {
                await database.GetContainer(_container.Id).DeleteContainerAsync();
                Console.WriteLine($"{Environment.NewLine}  deleted container {_container.Id}");
            }
        }
    }
}

Operazioni sugli elementi e le query

Creare un elemento

private static async Task CreateItemAsync(Container container)
{
    // Create a SalesOrder POCO object
    SalesOrder salesOrder1 = GetSalesOrderSample("Account1", "SalesOrder1");
    ItemResponse<SalesOrder> response = await container.CreateItemAsync(salesOrder1,
        new PartitionKey(salesOrder1.AccountNumber));
}

private static async Task RunBasicOperationsOnDynamicObjects(Container container)
{
    // Dynamic Object
    dynamic salesOrder = new
    {
        id = "SalesOrder5",
        AccountNumber = "Account1",
        PurchaseOrderNumber = "PO18009186470",
        OrderDate = DateTime.UtcNow,
        Total = 5.95,
    };
    Console.WriteLine("\nCreating item");
    ItemResponse<dynamic> response = await container.CreateItemAsync<dynamic>(
        salesOrder, new PartitionKey(salesOrder.AccountNumber));
    dynamic createdSalesOrder = response.Resource;
}

Leggere tutti gli elementi in un contenitore

private static async Task ReadAllItems(Container container)
{
    // Read all items in a container
    List<SalesOrder> allSalesForAccount1 = new List<SalesOrder>();

    using (FeedIterator<SalesOrder> resultSet = container.GetItemQueryIterator<SalesOrder>(
        queryDefinition: null,
        requestOptions: new QueryRequestOptions()
        {
            PartitionKey = new PartitionKey("Account1"),
            MaxItemCount = 5
        }))
    {
        while (resultSet.HasMoreResults)
        {
            FeedResponse<SalesOrder> response = await resultSet.ReadNextAsync();
            SalesOrder salesOrder = response.First();
            Console.WriteLine($"\n1.3.1 Account Number: {salesOrder.AccountNumber}; Id: {salesOrder.Id}");
            allSalesForAccount1.AddRange(response);
        }
    }
}

Eseguire query sugli elementi

Modifiche a SqlQuerySpec (QueryDefinition in v3.0 SDK)

La classe SqlQuerySpec in SDK v2 è stata rinominata in QueryDefinition nell'SDK v3.

SqlParameterCollection e SqlParameter sono stati rimossi. I parametri vengono ora aggiunti a QueryDefinition con un modello di generatore usando QueryDefinition.WithParameter. Gli utenti possono accedere ai parametri con QueryDefinition.GetQueryParameters

private static async Task QueryItems(Container container)
{
    // Query for items by a property other than Id
    QueryDefinition queryDefinition = new QueryDefinition(
        "select * from sales s where s.AccountNumber = @AccountInput")
        .WithParameter("@AccountInput", "Account1");

    List<SalesOrder> allSalesForAccount1 = new List<SalesOrder>();
    using (FeedIterator<SalesOrder> resultSet = container.GetItemQueryIterator<SalesOrder>(
        queryDefinition,
        requestOptions: new QueryRequestOptions()
        {
            PartitionKey = new PartitionKey("Account1"),
            MaxItemCount = 1
        }))
    {
        while (resultSet.HasMoreResults)
        {
            FeedResponse<SalesOrder> response = await resultSet.ReadNextAsync();
            SalesOrder sale = response.First();
            Console.WriteLine($"\n Account Number: {sale.AccountNumber}; Id: {sale.Id};");
            allSalesForAccount1.AddRange(response);
        }
    }
}

Eliminare un elemento

private static async Task DeleteItemAsync(Container container)
{
    ItemResponse<SalesOrder> response = await container.DeleteItemAsync<SalesOrder>(
        partitionKey: new PartitionKey("Account1"), id: "SalesOrder3");
}

Query del feed di modifiche

private static async Task QueryChangeFeedAsync(Container container)
{
    FeedIterator<SalesOrder> iterator = container.GetChangeFeedIterator<SalesOrder>(ChangeFeedStartFrom.Beginning(), ChangeFeedMode.Incremental);

    string continuation = null;
    while (iterator.HasMoreResults)
    {
        FeedResponse<SalesOrder> response = await iteratorForTheEntireContainer.ReadNextAsync();
    
        if (response.StatusCode == HttpStatusCode.NotModified)
        {
            // No new changes
            continuation = response.ContinuationToken;
            break;
        }
        else 
        {
            // Process the documents in response
        }
    }
}

Passaggi successivi