

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Pilote Amazon QLDB pour .NET
<a name="getting-started.dotnet"></a>

**Important**  
Avis de fin de support : les clients existants pourront utiliser Amazon QLDB jusqu'à la fin du support le 31 juillet 2025. Pour plus de détails, consultez [Migrer un registre Amazon QLDB vers Amazon Aurora PostgreSQL](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/).

Pour utiliser les données de votre registre, vous pouvez vous connecter à Amazon QLDB depuis votre application Microsoft .NET à l'aide d'un pilote fourni AWS . Le pilote cible **.NET Standard 2.0**. Plus précisément, il prend en charge **.NET Core (LTS) 2.1\$1** et **.NET Framework** 4.5.2\$1. Pour plus d'informations sur la compatibilité, consultez [.NET Standard](https://docs.microsoft.com/en-us/dotnet/standard/net-standard) sur le site *Microsoft Docs*.

Nous vous recommandons vivement d'utiliser le *mappeur d'objets Ion* pour éviter complètement de devoir effectuer une conversion manuelle entre les types Amazon Ion et les types C\$1 natifs.

Les rubriques suivantes décrivent comment démarrer avec le pilote QLDB pour .NET.

**Topics**
+ [Ressources pour les conducteurs](#getting-started.dotnet.resources)
+ [Prérequis](#getting-started.dotnet.prereqs)
+ [Installation](#getting-started.dotnet.install)
+ [Tutoriel de démarrage rapide](driver-quickstart-dotnet.md)
+ [Référence de livre de cuisine](driver-cookbook-dotnet.md)

## Ressources pour les conducteurs
<a name="getting-started.dotnet.resources"></a>

Pour plus d'informations sur les fonctionnalités prises en charge par le pilote .NET, consultez les ressources suivantes :
+ [Référence d'API](https://amazon-qldb-docs.s3.amazonaws.com/drivers/dotnet/1.4.1/api/Amazon.QLDB.Driver.html)
+ [Code source du pilote (GitHub)](https://github.com/awslabs/amazon-qldb-driver-dotnet)
+ [Exemple de code source d'application (GitHub)](https://github.com/aws-samples/amazon-qldb-dmv-sample-dotnet)
+ [Livre de recettes Amazon Ion](http://amzn.github.io/ion-docs/guides/cookbook.html)
+ [mappeur d'objets ioniques () GitHub](https://github.com/amzn/ion-object-mapper-dotnet)

## Prérequis
<a name="getting-started.dotnet.prereqs"></a>

Avant de commencer à utiliser le pilote QLDB pour .NET, vous devez effectuer les opérations suivantes :

1. Suivez les instructions AWS de configuration indiquées dans[Accès à Amazon QLDB](accessing.md). Cela inclut les éléments suivants :

   1. Inscrivez-vous pour AWS.

   1. Créez un utilisateur doté des autorisations QLDB appropriées.

   1. Accordez un accès programmatique pour le développement.

1. Téléchargez et installez le SDK .NET Core version 2.1 ou ultérieure à partir du site de [téléchargement de Microsoft .NET](https://dotnet.microsoft.com/download).

1. (Facultatif) Installez un environnement de développement intégré (IDE) de votre choix, tel que Visual Studio, Visual Studio pour Mac ou Visual Studio Code. Vous pouvez les télécharger sur le site de [Microsoft Visual Studio](https://visualstudio.microsoft.com/).

1. Configurez votre environnement de développement pour [AWS SDK pour .NET](https://aws.amazon.com/sdk-for-net):

   1. Configurez vos AWS informations d'identification. Nous vous recommandons de créer un fichier d'informations d'identification partagé.

      Pour obtenir des instructions, consultez [la section Configuration des AWS informations d'identification à l'aide d'un fichier d'informations d'identification](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-config-creds.html#creds-file) dans le *Guide du AWS SDK pour .NET développeur*.

   1. Définissez votre valeur par défaut Région AWS. Pour savoir comment procéder, consultez la section [Région AWS Sélection](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-region-selection.html).

      Pour obtenir la liste complète des régions disponibles, consultez la section [Points de terminaison et quotas Amazon QLDB](https://docs.aws.amazon.com/general/latest/gr/qldb.html) dans le. *Références générales AWS*

Vous pouvez ensuite configurer un exemple d'application de base et exécuter des exemples de code abrégé, ou vous pouvez installer le pilote dans un projet .NET existant.
+ Pour installer le pilote QLDB et AWS SDK pour .NET le dans un projet existant, passez à. [Installation](#getting-started.dotnet.install)
+ Pour configurer un projet et exécuter des exemples de codes abrégés illustrant les transactions de données de base sur un registre, consultez le[Tutoriel de démarrage rapide](driver-quickstart-dotnet.md).

## Installation
<a name="getting-started.dotnet.install"></a>

Utilisez le gestionnaire de NuGet packages pour installer le pilote QLDB pour .NET. Nous vous recommandons d'utiliser Visual Studio ou un IDE de votre choix pour ajouter des dépendances au projet. Le nom du package de pilotes est [Amazon.QLDB.Driver](https://www.nuget.org/packages/amazon.qldb.driver).

Par exemple, dans Visual Studio, ouvrez la **console NuGet Package Manager** dans le menu **Outils**. Entrez ensuite la commande suivante à l'`PM>`invite.

```
PM> Install-Package Amazon.QLDB.Driver
```

L'installation du pilote installe également ses dépendances, notamment les packages AWS SDK pour .NET et [Amazon Ion](ion.md).

### Installation du mappeur d'objets Ion
<a name="getting-started.dotnet.install.mapper"></a>

La version 1.3.0 du pilote QLDB pour .NET permet d'accepter et de renvoyer des types de données C\$1 natifs sans qu'il soit nécessaire de travailler avec Amazon Ion. Pour utiliser cette fonctionnalité, ajoutez le package suivant à votre projet.
+ [Amazon.QLdb.Driver.Serialization](https://www.nuget.org/packages/Amazon.QLDB.Driver.Serialization/) — Une bibliothèque capable de mapper des valeurs ioniques à de *vieux objets CLR (POCO) en* C\$1, et inversement. Ce mappeur d'objets Ion permet à votre application d'interagir directement avec les types de données C\$1 natifs sans avoir à travailler avec Ion. Pour un petit guide sur l'utilisation de cette bibliothèque, consultez le fichier [Serialization.md](https://github.com/awslabs/amazon-qldb-driver-dotnet/blob/master/SERIALIZATION.md) dans le référentiel. GitHub `awslabs/amazon-qldb-driver-dotnet`

Pour installer ce package, entrez la commande suivante.

```
PM> Install-Package Amazon.QLDB.Driver.Serialization
```

Pour des exemples de code abrégé expliquant comment exécuter des transactions de données de base sur un registre, consultez le[Référence de livre de cuisine](driver-cookbook-dotnet.md).

# Pilote Amazon QLDB pour .NET — Tutoriel de démarrage rapide
<a name="driver-quickstart-dotnet"></a>

**Important**  
Avis de fin de support : les clients existants pourront utiliser Amazon QLDB jusqu'à la fin du support le 31 juillet 2025. Pour plus de détails, consultez [Migrer un registre Amazon QLDB vers Amazon Aurora PostgreSQL](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/).

Dans ce didacticiel, vous apprendrez à configurer une application simple à l'aide du pilote Amazon QLDB pour .NET. Ce guide inclut les étapes d'installation du pilote et des exemples de code abrégé des opérations de base de *création, de lecture, de mise à jour et de suppression* (CRUD).

**Topics**
+ [Prérequis](#driver-quickstart-dotnet.prereqs)
+ [Étape 1 : Configurer votre projet](#driver-quickstart-dotnet.step-1)
+ [Étape 2 : Initialisation du pilote](#driver-quickstart-dotnet.step-2)
+ [Étape 3 : Création d'une table et d'un index](#driver-quickstart-dotnet.step-3)
+ [Étape 4 : Insérer un document](#driver-quickstart-dotnet.step-4)
+ [Étape 5 : Interrogez le document](#driver-quickstart-dotnet.step-5)
+ [Étape 6 : Mettre à jour le document](#driver-quickstart-dotnet.step-6)
+ [Exécution de l'application complète](#driver-quickstart-dotnet.complete)

## Prérequis
<a name="driver-quickstart-dotnet.prereqs"></a>

Avant de commencer, assurez-vous d'effectuer les opérations suivantes :

1. Complétez le dossier [Prérequis](getting-started.dotnet.md#getting-started.dotnet.prereqs) pour le pilote .NET, si ce n'est pas déjà fait. Cela inclut l'inscription AWS, l'octroi d'un accès programmatique pour le développement et l'installation du SDK .NET Core.

1. Créez un registre nommé`quick-start`.

   Pour savoir comment créer un registre, voir [Opérations de base pour les registres Amazon QLDB](ledger-management.basics.md) ou [Étape 1 : Création d'un nouveau registre](getting-started-step-1.md) dans *Commencer à utiliser la console*.

## Étape 1 : Configurer votre projet
<a name="driver-quickstart-dotnet.step-1"></a>

Configurez d'abord votre projet .NET.

1. Pour créer et exécuter un modèle d'application, entrez les `dotnet` commandes suivantes sur un terminal tel que *bash* ou *Command Prompt*. *PowerShell*

   ```
   $ dotnet new console --output Amazon.QLDB.QuickStartGuide
   $ dotnet run --project Amazon.QLDB.QuickStartGuide
   ```

   Ce modèle crée un dossier nommé`Amazon.QLDB.QuickStartGuide`. Dans ce dossier, il crée un projet portant le même nom et un fichier nommé`Program.cs`. Le programme contient du code qui affiche le résultat`Hello World!`.

1. Utilisez le gestionnaire de NuGet packages pour installer le pilote QLDB pour .NET. Nous vous recommandons d'utiliser Visual Studio ou un IDE de votre choix pour ajouter des dépendances à votre projet. Le nom du package de pilotes est [Amazon.QLDB.Driver](https://www.nuget.org/packages/amazon.qldb.driver).
   + Par exemple, dans Visual Studio, ouvrez la **console NuGet Package Manager** dans le menu **Outils**. Entrez ensuite la commande suivante à l'`PM>`invite.

     ```
     PM> Install-Package Amazon.QLDB.Driver
     ```
   + Vous pouvez également saisir les commandes suivantes sur votre terminal.

     ```
     $ cd Amazon.QLDB.QuickStartGuide
     $ dotnet add package Amazon.QLDB.Driver
     ```

   L'installation du pilote installe également ses dépendances, notamment les bibliothèques [AWS SDK pour .NET](https://aws.amazon.com/sdk-for-net)et [Amazon Ion](ion.md).

1. Installez la bibliothèque de sérialisation du pilote.

   ```
   PM> Install-Package Amazon.QLDB.Driver.Serialization
   ```

1. Ouvrez le fichier `Program.cs`.

   Ajoutez ensuite progressivement les exemples de code dans les étapes suivantes pour essayer certaines opérations CRUD de base. Vous pouvez également ignorer le step-by-step didacticiel et exécuter l'[application complète](#driver-quickstart-dotnet.complete) à la place.

**Note**  
**Choix entre synchrone et asynchrone APIs : le pilote fournit des** options synchrone et asynchrone. APIs Pour les applications très demandées qui traitent plusieurs demandes sans les bloquer, nous recommandons d'utiliser le mode asynchrone APIs pour améliorer les performances. Le pilote offre le mode synchrone APIs pour une commodité supplémentaire pour les bases de code existantes qui sont écrites de manière synchrone.  
Ce didacticiel inclut des exemples de code synchrone et asynchrone. Pour plus d'informations à ce sujet APIs, consultez le [IQldbpilote](https://amazon-qldb-docs.s3.amazonaws.com/drivers/dotnet/1.4.1/api/Amazon.QLDB.Driver.IQldbDriver.html) et les [IAsyncQldbDriver](https://amazon-qldb-docs.s3.amazonaws.com/drivers/dotnet/1.4.1/api/Amazon.QLDB.Driver.IAsyncQldbDriver.html)interfaces dans la documentation de l'API.
**Traitement des données Amazon Ion** : ce didacticiel fournit des exemples de code relatifs au traitement des données Amazon Ion à l'aide du [mappeur d'objets Ion](https://github.com/amzn/ion-object-mapper-dotnet) par défaut. QLDB a introduit le mappeur d'objets Ion dans la version 1.3.0 du pilote .NET. Le cas échéant, ce didacticiel fournit également des exemples de code utilisant la [bibliothèque Ion](https://github.com/amzn/ion-dotnet) standard comme alternative. Pour en savoir plus, consultez [Travailler avec Amazon Ion](driver-cookbook-dotnet.md#cookbook-dotnet.ion).

## Étape 2 : Initialisation du pilote
<a name="driver-quickstart-dotnet.step-2"></a>

Initialisez une instance du pilote qui se connecte au registre nommé. `quick-start` Ajoutez le code suivant à votre `Program.cs` fichier.

------
#### [ Async ]

```
using Amazon.QLDB.Driver;
using Amazon.QLDB.Driver.Generic;
using Amazon.QLDB.Driver.Serialization;

namespace Amazon.QLDB.QuickStartGuide
{
    class Program
    {
        public class Person
        {
            public string FirstName { get; set; }

            public string LastName { get; set; }

            public int Age { get; set; }

            public override string ToString()
            {
                return FirstName + ", " + LastName + ", " + Age.ToString();
            }
        }

        static async Task Main(string[] args)
        {
            Console.WriteLine("Create the async QLDB driver");
            IAsyncQldbDriver driver = AsyncQldbDriver.Builder()
                .WithLedger("quick-start")
                .WithSerializer(new ObjectSerializer())
                .Build();
        }
    }
}
```

------
#### [ Sync ]

```
using Amazon.QLDB.Driver;
using Amazon.QLDB.Driver.Generic;
using Amazon.QLDB.Driver.Serialization;

namespace Amazon.QLDB.QuickStartGuide
{
    class Program
    {
        public class Person
        {
            public string FirstName { get; set; }

            public string LastName { get; set; }

            public int Age { get; set; }

            public override string ToString()
            {
                return FirstName + ", " + LastName + ", " + Age.ToString();
            }
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Create the sync QLDB driver");
            IQldbDriver driver = QldbDriver.Builder()
                .WithLedger("quick-start")
                .WithSerializer(new ObjectSerializer())
                .Build();
        }
    }
}
```

------

### Utilisation de la bibliothèque Ion
<a name="driver-quickstart-dotnet.step-2.ion-library"></a>

------
#### [ Async ]

```
using System;
using System.Threading.Tasks;
using Amazon.IonDotnet.Tree;
using Amazon.IonDotnet.Tree.Impl;
using Amazon.QLDB.Driver;
using IAsyncResult = Amazon.QLDB.Driver.IAsyncResult;

namespace Amazon.QLDB.QuickStartGuide
{
    class Program
    {
        static IValueFactory valueFactory = new ValueFactory();

        static async Task Main(string[] args)
        {
            Console.WriteLine("Create the async QLDB driver");
            IAsyncQldbDriver driver = AsyncQldbDriver.Builder()
                .WithLedger("quick-start")
                .Build();
        }
    }
}
```

------
#### [ Sync ]

```
using System;
using Amazon.IonDotnet.Tree;
using Amazon.IonDotnet.Tree.Impl;
using Amazon.QLDB.Driver;

namespace Amazon.QLDB.QuickStartGuide
{
    class Program
    {
        static IValueFactory valueFactory = new ValueFactory();

        static void Main(string[] args)
        {
            Console.WriteLine("Create the sync QLDB Driver");
            IQldbDriver driver = QldbDriver.Builder()
                .WithLedger("quick-start")
                .Build();
        }
    }
}
```

------

## Étape 3 : Création d'une table et d'un index
<a name="driver-quickstart-dotnet.step-3"></a>

Pour le reste de ce didacticiel, jusqu'à l'*étape 6*, vous devez ajouter les exemples de code suivants à l'exemple de code précédent.

Au cours de cette étape, le code suivant montre comment exécuter `CREATE TABLE` des `CREATE INDEX` instructions. Il crée une table nommée `Person` et un index pour le `firstName` champ de cette table. Les [index](ql-reference.create-index.md) sont nécessaires pour optimiser les performances des requêtes et aider à limiter les exceptions de conflit liées au [contrôle optimiste de la simultanéité (OCC).](concurrency.md)

------
#### [ Async ]

```
Console.WriteLine("Creating the table and index");

// Creates the table and the index in the same transaction.
// Note: Any code within the lambda can potentially execute multiple times due to retries.
// For more information, see: https://docs.aws.amazon.com/qldb/latest/developerguide/driver-retry-policy
await driver.Execute(async txn =>
{
    await txn.Execute("CREATE TABLE Person");
    await txn.Execute("CREATE INDEX ON Person(firstName)");
});
```

------
#### [ Sync ]

```
Console.WriteLine("Creating the tables and index");

// Creates the table and the index in the same transaction.
// Note: Any code within the lambda can potentially execute multiple times due to retries.
// For more information, see: https://docs.aws.amazon.com/qldb/latest/developerguide/driver-retry-policy
driver.Execute(txn =>
{
    txn.Execute("CREATE TABLE Person");
    txn.Execute("CREATE INDEX ON Person(firstName)");
});
```

------

## Étape 4 : Insérer un document
<a name="driver-quickstart-dotnet.step-4"></a>

L'exemple de code suivant montre comment exécuter une `INSERT` instruction. QLDB prend en charge le langage de requête [partiQL](ql-reference.md) (compatible SQL) et le format de données [Amazon](ion.md) Ion (surensemble de JSON).

Ajoutez le code suivant qui insère un document dans le `Person` tableau.

------
#### [ Async ]

```
Console.WriteLine("Inserting a document");

Person myPerson = new Person {
    FirstName = "John",
    LastName = "Doe",
    Age = 32
};

await driver.Execute(async txn =>
{
    IQuery<Person> myQuery = txn.Query<Person>("INSERT INTO Person ?", myPerson);
    await txn.Execute(myQuery);
});
```

------
#### [ Sync ]

```
Console.WriteLine("Inserting a document");

Person myPerson = new Person {
    FirstName = "John",
    LastName = "Doe",
    Age = 32
};

driver.Execute(txn =>
{
    IQuery<Person> myQuery = txn.Query<Person>("INSERT INTO Person ?", myPerson);
    txn.Execute(myQuery);
});
```

------

### Utilisation de la bibliothèque Ion
<a name="driver-quickstart-dotnet.step-4.ion-library"></a>

------
#### [ Async ]

```
Console.WriteLine("Inserting a document");

// This is one way of creating Ion values. We can also use an IonLoader.
// For more details, see: https://docs.aws.amazon.com/qldb/latest/developerguide/driver-cookbook-dotnet.html#cookbook-dotnet.ion
IIonValue ionPerson = valueFactory.NewEmptyStruct();
ionPerson.SetField("firstName", valueFactory.NewString("John"));
ionPerson.SetField("lastName", valueFactory.NewString("Doe"));
ionPerson.SetField("age", valueFactory.NewInt(32));

await driver.Execute(async txn =>
{
    await txn.Execute("INSERT INTO Person ?", ionPerson);
});
```

------
#### [ Sync ]

```
Console.WriteLine("Inserting a document");

// This is one way of creating Ion values, we can also use an IonLoader.
// For more details, see: https://docs.aws.amazon.com/qldb/latest/developerguide/driver-cookbook-dotnet.html#cookbook-dotnet.ion
IIonValue ionPerson = valueFactory.NewEmptyStruct();
ionPerson.SetField("firstName", valueFactory.NewString("John"));
ionPerson.SetField("lastName", valueFactory.NewString("Doe"));
ionPerson.SetField("age", valueFactory.NewInt(32));

driver.Execute(txn =>
{
    txn.Execute("INSERT INTO Person ?", ionPerson);
});
```

------

**Astuce**  
Pour insérer plusieurs documents à l'aide d'une seule [INSERT](ql-reference.insert.md) instruction, vous pouvez transmettre un paramètre de type [liste d'ions](driver-working-with-ion.md#driver-ion-list) à l'instruction comme suit.  

```
// people is an Ion list
txn.Execute("INSERT INTO Person ?", people);
```
Vous ne placez pas la variable placeholder (`?`) entre crochets (`<<...>>`) lorsque vous transmettez une liste d'ions. *Dans les instructions partiQL manuelles, les crochets à double angle indiquent une collection non ordonnée appelée sac.*

## Étape 5 : Interrogez le document
<a name="driver-quickstart-dotnet.step-5"></a>

L'exemple de code suivant montre comment exécuter une `SELECT` instruction.

Ajoutez le code suivant qui interroge un document à partir de la `Person` table.

------
#### [ Async ]

```
Console.WriteLine("Querying the table");

// The result from driver.Execute() is buffered into memory because once the
// transaction is committed, streaming the result is no longer possible.
IAsyncResult<Person> selectResult = await driver.Execute(async txn =>
{
    IQuery<Person> myQuery = txn.Query<Person>("SELECT * FROM Person WHERE FirstName = ?", "John");
    return await txn.Execute(myQuery);
});

await foreach (Person person in selectResult)
{
    Console.WriteLine(person);
    // John, Doe, 32
}
```

------
#### [ Sync ]

```
Console.WriteLine("Querying the table");

// The result from driver.Execute() is buffered into memory because once the
// transaction is committed, streaming the result is no longer possible.
IResult<Person> selectResult = driver.Execute(txn =>
{
    IQuery<Person> myQuery = txn.Query<Person>("SELECT * FROM Person WHERE FirstName = ?", "John");
    return txn.Execute(myQuery);
});

foreach (Person person in selectResult)
{
    Console.WriteLine(person);
    // John, Doe, 32
}
```

------

### Utilisation de la bibliothèque Ion
<a name="driver-quickstart-dotnet.step-5.ion-library"></a>

------
#### [ Async ]

```
Console.WriteLine("Querying the table");

IIonValue ionFirstName = valueFactory.NewString("John");

// The result from driver.Execute() is buffered into memory because once the
// transaction is committed, streaming the result is no longer possible.
IAsyncResult selectResult = await driver.Execute(async txn =>
{
    return await txn.Execute("SELECT * FROM Person WHERE firstName = ?", ionFirstName);
});

await foreach (IIonValue row in selectResult)
{
    Console.WriteLine(row.GetField("firstName").StringValue);
    Console.WriteLine(row.GetField("lastName").StringValue);
    Console.WriteLine(row.GetField("age").IntValue);
}
```

------
#### [ Sync ]

```
Console.WriteLine("Querying the table");

IIonValue ionFirstName = valueFactory.NewString("John");

// The result from driver.Execute() is buffered into memory because once the
// transaction is committed, streaming the result is no longer possible.
IResult selectResult = driver.Execute(txn =>
{
    return txn.Execute("SELECT * FROM Person WHERE firstName = ?", ionFirstName);
});

foreach (IIonValue row in selectResult)
{
    Console.WriteLine(row.GetField("firstName").StringValue);
    Console.WriteLine(row.GetField("lastName").StringValue);
    Console.WriteLine(row.GetField("age").IntValue);
}
```

------

Cet exemple utilise un point d'interrogation (`?`) comme espace réservé aux variables pour transmettre les informations du document à l'instruction. Lorsque vous utilisez des espaces réservés, vous devez transmettre une valeur de type`IonValue`.

## Étape 6 : Mettre à jour le document
<a name="driver-quickstart-dotnet.step-6"></a>

L'exemple de code suivant montre comment exécuter une `UPDATE` instruction.

1. Ajoutez le code suivant qui met à jour un document dans le `Person` tableau en le mettant à jour `age` vers 42.

------
#### [ Async ]

   ```
   Console.WriteLine("Updating the document");
   
   await driver.Execute(async txn =>
   {
       IQuery<Person> myQuery = txn.Query<Person>("UPDATE Person SET Age = ? WHERE FirstName = ?", 42, "John");
       await txn.Execute(myQuery);
   });
   ```

------
#### [ Sync ]

   ```
   Console.WriteLine("Updating the document");
   
   driver.Execute(txn =>
   {
       IQuery<Person> myQuery = txn.Query<Person>("UPDATE Person SET Age = ? WHERE FirstName = ?", 42, "John");
       txn.Execute(myQuery);
   });
   ```

------

1. Interrogez à nouveau le document pour voir la valeur mise à jour.

------
#### [ Async ]

   ```
   Console.WriteLine("Querying the table for the updated document");
   
   IAsyncResult<Person> updateResult = await driver.Execute(async txn =>
   {
       IQuery<Person> myQuery = txn.Query<Person>("SELECT * FROM Person WHERE FirstName = ?", "John");
       return await txn.Execute(myQuery);
   });
   
   await foreach (Person person in updateResult)
   {
       Console.WriteLine(person);
       // John, Doe, 42
   }
   ```

------
#### [ Sync ]

   ```
   Console.WriteLine("Querying the table for the updated document");
   
   IResult<Person> updateResult = driver.Execute(txn =>
   {
       IQuery<Person> myQuery = txn.Query<Person>("SELECT * FROM Person WHERE FirstName = ?", "John");
       return txn.Execute(myQuery);
   });
   
   foreach (Person person in updateResult)
   {
       Console.WriteLine(person);
       // John, Doe, 42
   }
   ```

------

1. Pour exécuter l'application, entrez la commande suivante depuis le répertoire parent du répertoire de votre `Amazon.QLDB.QuickStartGuide` projet.

   ```
   $ dotnet run --project Amazon.QLDB.QuickStartGuide
   ```

### Utilisation de la bibliothèque Ion
<a name="driver-quickstart-dotnet.step-6.ion-library"></a>

1. Ajoutez le code suivant qui met à jour un document dans le `Person` tableau en le mettant à jour `age` vers 42.

------
#### [ Async ]

   ```
   Console.WriteLine("Updating the document");
   
   IIonValue ionIntAge = valueFactory.NewInt(42);
   IIonValue ionFirstName2 = valueFactory.NewString("John");
   
   await driver.Execute(async txn =>
   {
       await txn.Execute("UPDATE Person SET age = ? WHERE firstName = ?", ionIntAge, ionFirstName2);
   });
   ```

------
#### [ Sync ]

   ```
   Console.WriteLine("Updating a document");
   
   IIonValue ionIntAge = valueFactory.NewInt(42);
   IIonValue ionFirstName2 = valueFactory.NewString("John");
   
   driver.Execute(txn =>
   {
       txn.Execute("UPDATE Person SET age = ? WHERE firstName = ?", ionIntAge, ionFirstName2);
   });
   ```

------

1. Interrogez à nouveau le document pour voir la valeur mise à jour.

------
#### [ Async ]

   ```
   Console.WriteLine("Querying the table for the updated document");
   
   IIonValue ionFirstName3 = valueFactory.NewString("John");
   
   IAsyncResult updateResult = await driver.Execute(async txn =>
   {
       return await txn.Execute("SELECT * FROM Person WHERE firstName = ?", ionFirstName3 );
   });
   
   await foreach (IIonValue row in updateResult)
   {
       Console.WriteLine(row.GetField("firstName").StringValue);
       Console.WriteLine(row.GetField("lastName").StringValue);
       Console.WriteLine(row.GetField("age").IntValue);
   }
   ```

------
#### [ Sync ]

   ```
   Console.WriteLine("Querying the table for the updated document");
   
   IIonValue ionFirstName3 = valueFactory.NewString("John");
   
   IResult updateResult = driver.Execute(txn =>
   {
       return txn.Execute("SELECT * FROM Person WHERE firstName = ?", ionFirstName3);
   });
   
   foreach (IIonValue row in updateResult)
   {
       Console.WriteLine(row.GetField("firstName").StringValue);
       Console.WriteLine(row.GetField("lastName").StringValue);
       Console.WriteLine(row.GetField("age").IntValue);
   }
   ```

------

1. Pour exécuter l'application, entrez la commande suivante depuis le répertoire parent du répertoire de votre `Amazon.QLDB.QuickStartGuide` projet.

   ```
   $ dotnet run --project Amazon.QLDB.QuickStartGuide
   ```

## Exécution de l'application complète
<a name="driver-quickstart-dotnet.complete"></a>

L'exemple de code suivant représente la version complète de l'`Program.cs`application. Au lieu d'effectuer les étapes précédentes individuellement, vous pouvez également copier et exécuter cet exemple de code du début à la fin. Cette application montre certaines opérations CRUD de base sur le registre nommé. `quick-start`

**Note**  
Avant d'exécuter ce code, assurez-vous qu'aucune table active n'est déjà nommée `Person` dans le `quick-start` registre.

------
#### [ Async ]

```
using Amazon.QLDB.Driver;
using Amazon.QLDB.Driver.Generic;
using Amazon.QLDB.Driver.Serialization;

namespace Amazon.QLDB.QuickStartGuide
{
    class Program
    {
        public class Person
        {
            public string FirstName { get; set; }

            public string LastName { get; set; }

            public int Age { get; set; }

            public override string ToString()
            {
                return FirstName + ", " + LastName + ", " + Age.ToString();
            }
        }

        static async Task Main(string[] args)
        {
            Console.WriteLine("Create the async QLDB driver");
            IAsyncQldbDriver driver = AsyncQldbDriver.Builder()
                .WithLedger("quick-start")
                .WithSerializer(new ObjectSerializer())
                .Build();

            Console.WriteLine("Creating the table and index");

            // Creates the table and the index in the same transaction.
            // Note: Any code within the lambda can potentially execute multiple times due to retries.
            // For more information, see: https://docs.aws.amazon.com/qldb/latest/developerguide/driver-retry-policy
            await driver.Execute(async txn =>
            {
                await txn.Execute("CREATE TABLE Person");
                await txn.Execute("CREATE INDEX ON Person(firstName)");
            });

            Console.WriteLine("Inserting a document");

            Person myPerson = new Person {
                FirstName = "John",
                LastName = "Doe",
                Age = 32
            };

            await driver.Execute(async txn =>
            {
                IQuery<Person> myQuery = txn.Query<Person>("INSERT INTO Person ?", myPerson);
                await txn.Execute(myQuery);
            });

            Console.WriteLine("Querying the table");

            // The result from driver.Execute() is buffered into memory because once the
            // transaction is committed, streaming the result is no longer possible.
            IAsyncResult<Person> selectResult = await driver.Execute(async txn =>
            {
                IQuery<Person> myQuery = txn.Query<Person>("SELECT * FROM Person WHERE FirstName = ?", "John");
                return await txn.Execute(myQuery);
            });

            await foreach (Person person in selectResult)
            {
                Console.WriteLine(person);
                // John, Doe, 32
            }

            Console.WriteLine("Updating the document");

            await driver.Execute(async txn =>
            {
                IQuery<Person> myQuery = txn.Query<Person>("UPDATE Person SET Age = ? WHERE FirstName = ?", 42, "John");
                await txn.Execute(myQuery);
            });

            Console.WriteLine("Querying the table for the updated document");

            IAsyncResult<Person> updateResult = await driver.Execute(async txn =>
            {
                IQuery<Person> myQuery = txn.Query<Person>("SELECT * FROM Person WHERE FirstName = ?", "John");
                return await txn.Execute(myQuery);
            });

            await foreach (Person person in updateResult)
            {
                Console.WriteLine(person);
                // John, Doe, 42
            }
        }
    }
}
```

------
#### [ Sync ]

```
using Amazon.QLDB.Driver;
using Amazon.QLDB.Driver.Generic;
using Amazon.QLDB.Driver.Serialization;

namespace Amazon.QLDB.QuickStartGuide
{
    class Program
    {
        public class Person
        {
            public string FirstName { get; set; }

            public string LastName { get; set; }

            public int Age { get; set; }

            public override string ToString()
            {
                return FirstName + ", " + LastName + ", " + Age.ToString();
            }
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Create the sync QLDB driver");
            IQldbDriver driver = QldbDriver.Builder()
                .WithLedger("quick-start")
                .WithSerializer(new ObjectSerializer())
                .Build();

            Console.WriteLine("Creating the table and index");

            // Creates the table and the index in the same transaction.
            // Note: Any code within the lambda can potentially execute multiple times due to retries.
            // For more information, see: https://docs.aws.amazon.com/qldb/latest/developerguide/driver-retry-policy
            driver.Execute(txn =>
            {
                txn.Execute("CREATE TABLE Person");
                txn.Execute("CREATE INDEX ON Person(firstName)");
            });

            Console.WriteLine("Inserting a document");

            Person myPerson = new Person {
                FirstName = "John",
                LastName = "Doe",
                Age = 32
            };

            driver.Execute(txn =>
            {
                IQuery<Person> myQuery = txn.Query<Person>("INSERT INTO Person ?", myPerson);
                txn.Execute(myQuery);
            });

            Console.WriteLine("Querying the table");

            // The result from driver.Execute() is buffered into memory because once the
            // transaction is committed, streaming the result is no longer possible.
            IResult<Person> selectResult = driver.Execute(txn =>
            {
                IQuery<Person> myQuery = txn.Query<Person>("SELECT * FROM Person WHERE FirstName = ?", "John");
                return txn.Execute(myQuery);
            });

            foreach (Person person in selectResult)
            {
                Console.WriteLine(person);
                // John, Doe, 32
            }

            Console.WriteLine("Updating the document");

            driver.Execute(txn =>
            {
                IQuery<Person> myQuery = txn.Query<Person>("UPDATE Person SET Age = ? WHERE FirstName = ?", 42, "John");
                txn.Execute(myQuery);
            });

            Console.WriteLine("Querying the table for the updated document");

            IResult<Person> updateResult = driver.Execute(txn =>
            {
                IQuery<Person> myQuery = txn.Query<Person>("SELECT * FROM Person WHERE FirstName = ?", "John");
                return txn.Execute(myQuery);
            });

            foreach (Person person in updateResult)
            {
                Console.WriteLine(person);
                // John, Doe, 42
            }

        }
    }
}
```

------

### Utilisation de la bibliothèque Ion
<a name="driver-quickstart-dotnet.complete.ion-library"></a>

------
#### [ Async ]

```
using System;
using System.Threading.Tasks;
using Amazon.IonDotnet.Tree;
using Amazon.IonDotnet.Tree.Impl;
using Amazon.QLDB.Driver;
using IAsyncResult = Amazon.QLDB.Driver.IAsyncResult;

namespace Amazon.QLDB.QuickStartGuide
{
    class Program
    {
        static IValueFactory valueFactory = new ValueFactory();

        static async Task Main(string[] args)
        {
            Console.WriteLine("Create the async QLDB driver");
            IAsyncQldbDriver driver = AsyncQldbDriver.Builder()
                .WithLedger("quick-start")
                .Build();

            Console.WriteLine("Creating the table and index");

            // Creates the table and the index in the same transaction.
            // Note: Any code within the lambda can potentially execute multiple times due to retries.
            // For more information, see: https://docs.aws.amazon.com/qldb/latest/developerguide/driver-retry-policy
            await driver.Execute(async txn =>
            {
                await txn.Execute("CREATE TABLE Person");
                await txn.Execute("CREATE INDEX ON Person(firstName)");
            });

            Console.WriteLine("Inserting a document");

            // This is one way of creating Ion values. We can also use an IonLoader.
            // For more details, see: https://docs.aws.amazon.com/qldb/latest/developerguide/driver-cookbook-dotnet.html#cookbook-dotnet.ion
            IIonValue ionPerson = valueFactory.NewEmptyStruct();
            ionPerson.SetField("firstName", valueFactory.NewString("John"));
            ionPerson.SetField("lastName", valueFactory.NewString("Doe"));
            ionPerson.SetField("age", valueFactory.NewInt(32));

            await driver.Execute(async txn =>
            {
                await txn.Execute("INSERT INTO Person ?", ionPerson);
            });

            Console.WriteLine("Querying the table");

            IIonValue ionFirstName = valueFactory.NewString("John");

            // The result from driver.Execute() is buffered into memory because once the
            // transaction is committed, streaming the result is no longer possible.
            IAsyncResult selectResult = await driver.Execute(async txn =>
            {
                return await txn.Execute("SELECT * FROM Person WHERE firstName = ?", ionFirstName);
            });

            await foreach (IIonValue row in selectResult)
            {
                Console.WriteLine(row.GetField("firstName").StringValue);
                Console.WriteLine(row.GetField("lastName").StringValue);
                Console.WriteLine(row.GetField("age").IntValue);
            }

            Console.WriteLine("Updating the document");

            IIonValue ionIntAge = valueFactory.NewInt(42);
            IIonValue ionFirstName2 = valueFactory.NewString("John");

            await driver.Execute(async txn =>
            {
                await txn.Execute("UPDATE Person SET age = ? WHERE firstName = ?", ionIntAge, ionFirstName2);
            });

            Console.WriteLine("Querying the table for the updated document");

            IIonValue ionFirstName3 = valueFactory.NewString("John");

            IAsyncResult updateResult = await driver.Execute(async txn =>
            {
                return await txn.Execute("SELECT * FROM Person WHERE firstName = ?", ionFirstName3);
            });

            await foreach (IIonValue row in updateResult)
            {
                Console.WriteLine(row.GetField("firstName").StringValue);
                Console.WriteLine(row.GetField("lastName").StringValue);
                Console.WriteLine(row.GetField("age").IntValue);
            }
        }
    }
}
```

------
#### [ Sync ]

```
using System;
using Amazon.IonDotnet.Tree;
using Amazon.IonDotnet.Tree.Impl;
using Amazon.QLDB.Driver;

namespace Amazon.QLDB.QuickStartGuide
{
    class Program
    {
        static IValueFactory valueFactory = new ValueFactory();

        static void Main(string[] args)
        {
            Console.WriteLine("Create the sync QLDB Driver");
            IQldbDriver driver = QldbDriver.Builder()
                .WithLedger("quick-start")
                .Build();

            Console.WriteLine("Creating the tables and index");

            // Creates the table and the index in the same transaction.
            // Note: Any code within the lambda can potentially execute multiple times due to retries.
            // For more information, see: https://docs.aws.amazon.com/qldb/latest/developerguide/driver-retry-policy
            driver.Execute(txn =>
            {
                txn.Execute("CREATE TABLE Person");
                txn.Execute("CREATE INDEX ON Person(firstName)");
            });

            Console.WriteLine("Inserting a document");

            // This is one way of creating Ion values. We can also use an IonLoader.
            // For more details, see: https://docs.aws.amazon.com/qldb/latest/developerguide/driver-cookbook-dotnet.html#cookbook-dotnet.ion
            IIonValue ionPerson = valueFactory.NewEmptyStruct();
            ionPerson.SetField("firstName", valueFactory.NewString("John"));
            ionPerson.SetField("lastName", valueFactory.NewString("Doe"));
            ionPerson.SetField("age", valueFactory.NewInt(32));

            driver.Execute(txn =>
            {
                txn.Execute("INSERT INTO Person ?", ionPerson);
            });

            Console.WriteLine("Querying the table");

            IIonValue ionFirstName = valueFactory.NewString("John");

            // The result from driver.Execute() is buffered into memory because once the
            // transaction is committed, streaming the result is no longer possible.
            IResult selectResult = driver.Execute(txn =>
            {
                return txn.Execute("SELECT * FROM Person WHERE firstName = ?", ionFirstName);
            });

            foreach (IIonValue row in selectResult)
            {
                Console.WriteLine(row.GetField("firstName").StringValue);
                Console.WriteLine(row.GetField("lastName").StringValue);
                Console.WriteLine(row.GetField("age").IntValue);
            }

            Console.WriteLine("Updating a document");

            IIonValue ionIntAge = valueFactory.NewInt(42);
            IIonValue ionFirstName2 = valueFactory.NewString("John");

            driver.Execute(txn =>
            {
                txn.Execute("UPDATE Person SET age = ? WHERE firstName = ?", ionIntAge, ionFirstName2);
            });

            Console.WriteLine("Querying the table for the updated document");

            IIonValue ionFirstName3 = valueFactory.NewString("John");

            IResult updateResult = driver.Execute(txn =>
            {
                return txn.Execute("SELECT * FROM Person WHERE firstName = ?", ionFirstName3);
            });

            foreach (IIonValue row in updateResult)
            {
                Console.WriteLine(row.GetField("firstName").StringValue);
                Console.WriteLine(row.GetField("lastName").StringValue);
                Console.WriteLine(row.GetField("age").IntValue);
            }
        }
    }
}
```

------

Pour exécuter l'application complète, entrez la commande suivante depuis le répertoire parent du répertoire de votre `Amazon.QLDB.QuickStartGuide` projet.

```
$ dotnet run --project Amazon.QLDB.QuickStartGuide
```

# Pilote Amazon QLDB pour .NET — Guide de référence du livre de recettes
<a name="driver-cookbook-dotnet"></a>

**Important**  
Avis de fin de support : les clients existants pourront utiliser Amazon QLDB jusqu'à la fin du support le 31 juillet 2025. Pour plus de détails, consultez [Migrer un registre Amazon QLDB vers Amazon Aurora PostgreSQL](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/).

Ce guide de référence présente les cas d'utilisation courants du pilote Amazon QLDB pour .NET. Il fournit des exemples de code C\$1 qui montrent comment utiliser le pilote pour exécuter des opérations de base de *création, de lecture, de mise à jour et de suppression* (CRUD). Il inclut également des exemples de code pour le traitement des données Amazon Ion. En outre, ce guide met en évidence les meilleures pratiques pour rendre les transactions idempotentes et mettre en œuvre des contraintes d'unicité.

**Note**  
Cette rubrique fournit des exemples de code relatifs au traitement des données Amazon Ion à l'aide du [mappeur d'objets Ion](https://github.com/amzn/ion-object-mapper-dotnet) par défaut. QLDB a introduit le mappeur d'objets Ion dans la version 1.3.0 du pilote .NET. Le cas échéant, cette rubrique fournit également des exemples de code utilisant la [bibliothèque Ion](https://github.com/amzn/ion-dotnet) standard comme alternative. Pour en savoir plus, consultez [Travailler avec Amazon Ion](#cookbook-dotnet.ion).

**Contents**
+ [Importation du pilote](#cookbook-dotnet.importing)
+ [Instanciation du pilote](#cookbook-dotnet.instantiating)
+ [Opérations CRUD](#cookbook-dotnet.crud)
  + [Création de tables](#cookbook-dotnet.crud.creating-tables)
  + [Création d'index](#cookbook-dotnet.crud.creating-indexes)
  + [Lecture de documents](#cookbook-dotnet.crud.reading)
    + [Utilisation des paramètres de requête](#cookbook-dotnet.reading-using-params)
  + [Insertion de documents](#cookbook-dotnet.crud.inserting)
    + [Insertion de plusieurs documents dans une seule déclaration](#cookbook-dotnet.crud.inserting.multiple)
  + [Mettre à jour des documents](#cookbook-dotnet.crud.updating)
  + [Supprimer des documents](#cookbook-dotnet.crud.deleting)
  + [Exécution de plusieurs instructions dans une transaction](#cookbook-dotnet.crud.multi-statement)
  + [Logique des nouvelles tentatives](#cookbook-dotnet.crud.retry-logic)
  + [Mettre en œuvre des contraintes d'unicité](#cookbook-dotnet.crud.uniqueness-constraints)
+ [Travailler avec Amazon Ion](#cookbook-dotnet.ion)
  + [Importation du module Ion](#cookbook-dotnet.ion.import)
  + [Création de types d'ions](#cookbook-dotnet.ion.creating-types)
  + [Obtenir un dump binaire d'ions](#cookbook-dotnet.ion.getting-binary)
  + [Obtenir un vidage de texte Ion](#cookbook-dotnet.ion.getting-text)

## Importation du pilote
<a name="cookbook-dotnet.importing"></a>

L'exemple de code suivant importe le pilote.

```
using Amazon.QLDB.Driver;
using Amazon.QLDB.Driver.Generic;
using Amazon.QLDB.Driver.Serialization;
```

### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.importing.ion-library"></a>

```
using Amazon.QLDB.Driver;
using Amazon.IonDotnet.Builders;
```

## Instanciation du pilote
<a name="cookbook-dotnet.instantiating"></a>

L'exemple de code suivant crée une instance du pilote qui se connecte à un nom de registre spécifié à l'aide des paramètres par défaut.

------
#### [ Async ]

```
IAsyncQldbDriver driver = AsyncQldbDriver.Builder()
    .WithLedger("vehicle-registration")
    // Add Serialization library
    .WithSerializer(new ObjectSerializer())
    .Build();
```

------
#### [ Sync ]

```
IQldbDriver driver = QldbDriver.Builder()
    .WithLedger("vehicle-registration")
    // Add Serialization library
    .WithSerializer(new ObjectSerializer())
    .Build();
```

------

### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.instantiating.ion-library"></a>

------
#### [ Async ]

```
IAsyncQldbDriver driver = AsyncQldbDriver.Builder().WithLedger("vehicle-registration").Build();
```

------
#### [ Sync ]

```
IQldbDriver driver = QldbDriver.Builder().WithLedger("vehicle-registration").Build();
```

------

## Opérations CRUD
<a name="cookbook-dotnet.crud"></a>

QLDB *exécute des opérations de création, de lecture, de mise à jour et* de suppression (CRUD) dans le cadre d'une transaction.

**Avertissement**  
La meilleure pratique consiste à rendre vos transactions d'écriture strictement idempotentes.

**Rendre les transactions idempotentes**

Nous vous recommandons de rendre les transactions d'écriture idempotentes afin d'éviter tout effet secondaire inattendu en cas de nouvelle tentative. Une transaction est *idempotente* si elle peut être exécutée plusieurs fois et produire des résultats identiques à chaque fois.

Prenons l'exemple d'une transaction qui insère un document dans une table nommée`Person`. La transaction doit d'abord vérifier si le document existe déjà dans le tableau. Sans cette vérification, le tableau peut se retrouver avec des documents dupliqués.

Supposons que QLDB valide correctement la transaction côté serveur, mais que le client expire en attendant une réponse. Si la transaction n'est pas idempotente, le même document peut être inséré plusieurs fois en cas de nouvelle tentative.

**Utilisation d'index pour éviter l'analyse complète des tables**

Nous vous recommandons également d'exécuter des instructions contenant une clause de `WHERE` prédicat à l'aide d'un opérateur d'*égalité* sur un champ indexé ou un identifiant de document ; par exemple, `WHERE indexedField = 123` ou. `WHERE indexedField IN (456, 789)` Sans cette recherche indexée, QLDB doit effectuer une analyse des tables, ce qui peut entraîner des délais d'expiration des transactions *ou des conflits de contrôle de simultanéité optimistes* (OCC).

Pour plus d'informations sur l'OCC, consultez[Modèle de simultanéité Amazon QLDB](concurrency.md).

**Transactions créées implicitement**

Le pilote [Amazon.QLDB. ](https://amazon-qldb-docs.s3.amazonaws.com/drivers/dotnet/1.4.1/api/Amazon.QLDB.Driver.IQldbDriver.html)IQldb[La méthode Driver.Execute accepte une fonction lambda qui reçoit une instance de Amazon.QLDB.Driver. TransactionExecutor](https://amazon-qldb-docs.s3.amazonaws.com/drivers/dotnet/1.4.1/api/Amazon.QLDB.Driver.TransactionExecutor.html), que vous pouvez utiliser pour exécuter des instructions. L'instance de `TransactionExecutor` enveloppe une transaction créée implicitement.

Vous pouvez exécuter des instructions dans la fonction lambda en utilisant la `Execute` méthode de l'exécuteur de transactions. Le pilote valide implicitement la transaction lorsque la fonction lambda revient.

Les sections suivantes montrent comment exécuter des opérations CRUD de base, spécifier une logique de nouvelle tentative personnalisée et implémenter des contraintes d'unicité.

**Contents**
+ [Création de tables](#cookbook-dotnet.crud.creating-tables)
+ [Création d'index](#cookbook-dotnet.crud.creating-indexes)
+ [Lecture de documents](#cookbook-dotnet.crud.reading)
  + [Utilisation des paramètres de requête](#cookbook-dotnet.reading-using-params)
+ [Insertion de documents](#cookbook-dotnet.crud.inserting)
  + [Insertion de plusieurs documents dans une seule déclaration](#cookbook-dotnet.crud.inserting.multiple)
+ [Mettre à jour des documents](#cookbook-dotnet.crud.updating)
+ [Supprimer des documents](#cookbook-dotnet.crud.deleting)
+ [Exécution de plusieurs instructions dans une transaction](#cookbook-dotnet.crud.multi-statement)
+ [Logique des nouvelles tentatives](#cookbook-dotnet.crud.retry-logic)
+ [Mettre en œuvre des contraintes d'unicité](#cookbook-dotnet.crud.uniqueness-constraints)

### Création de tables
<a name="cookbook-dotnet.crud.creating-tables"></a>

------
#### [ Async ]

```
IAsyncResult<Table> createResult = await driver.Execute(async txn =>
{
    IQuery<Table> query = txn.Query<Table>("CREATE TABLE Person");
    return await txn.Execute(query);
});

await foreach (var result in createResult)
{
    Console.WriteLine("{ tableId: " + result.TableId + " }");
    // The statement returns the created table ID:
    // { tableId: 4o5Uk09OcjC6PpJpLahceE }
}
```

------
#### [ Sync ]

```
IResult<Table> createResult = driver.Execute( txn =>
{
    IQuery<Table> query = txn.Query<Table>("CREATE TABLE Person");
    return txn.Execute(query);
});

foreach (var result in createResult)
{
    Console.WriteLine("{ tableId: " + result.TableId + " }");
    // The statement returns the created table ID:
    // { tableId: 4o5Uk09OcjC6PpJpLahceE }
}
```

------

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.creating-tables.ion-library"></a>

------
#### [ Async ]

```
// The result from driver.Execute() is buffered into memory because once the
// transaction is committed, streaming the result is no longer possible.
IAsyncResult result = await driver.Execute(async txn =>
{
    return await txn.Execute("CREATE TABLE Person");
});

await foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // The statement returns the created table ID:
    // {
    //    tableId: "4o5Uk09OcjC6PpJpLahceE"
    // }
}
```

------
#### [ Sync ]

```
// The result from driver.Execute() is buffered into memory because once the
// transaction is committed, streaming the result is no longer possible.
IResult result = driver.Execute(txn =>
{
    return txn.Execute("CREATE TABLE Person");
});

foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // The statement returns the created table ID:
    // {
    //    tableId: "4o5Uk09OcjC6PpJpLahceE"
    // }
}
```

------

### Création d'index
<a name="cookbook-dotnet.crud.creating-indexes"></a>

------
#### [ Async ]

```
IAsyncResult<Table> createResult = await driver.Execute(async txn =>
{
    IQuery<Table> query = txn.Query<Table>("CREATE INDEX ON Person(firstName)");
    return await txn.Execute(query);
});

await foreach (var result in createResult)
{
    Console.WriteLine("{ tableId: " + result.TableId + " }");
    // The statement returns the updated table ID:
    // { tableId: 4o5Uk09OcjC6PpJpLahceE }
}
```

------
#### [ Sync ]

```
IResult<Table> createResult = driver.Execute(txn =>
{
    IQuery<Table> query = txn.Query<Table>("CREATE INDEX ON Person(firstName)");
    return txn.Execute(query);
});

foreach (var result in createResult)
{
    Console.WriteLine("{ tableId: " + result.TableId + " }");
    // The statement returns the updated table ID:
    // { tableId: 4o5Uk09OcjC6PpJpLahceE }
}
```

------

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.creating-indexes.ion-library"></a>

------
#### [ Async ]

```
IAsyncResult result = await driver.Execute(async txn =>
{
    return await txn.Execute("CREATE INDEX ON Person(GovId)");
});

await foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // The statement returns the updated table ID:
    // {
    //    tableId: "4o5Uk09OcjC6PpJpLahceE"
    // }
}
```

------
#### [ Sync ]

```
IResult result = driver.Execute(txn =>
{
    return txn.Execute("CREATE INDEX ON Person(GovId)");
});

foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // The statement returns the updated table ID:
    // {
    //    tableId: "4o5Uk09OcjC6PpJpLahceE"
    // }
}
```

------

### Lecture de documents
<a name="cookbook-dotnet.crud.reading"></a>

```
// Assumes that Person table has documents as follows:
// { "GovId": "TOYENC486FH", "FirstName" : "Brent" }
// Person class is defined as follows:
// public class Person
// {
//     public string GovId { get; set; }
//     public string FirstName { get; set; }
//  }

IAsyncResult<Person> result = await driver.Execute(async txn =>
{
    return await txn.Execute(txn.Query<Person>("SELECT * FROM Person WHERE GovId = 'TOYENC486FH'"));
});

await foreach (Person person in result)
{
    Console.WriteLine(person.GovId); // Prints TOYENC486FH.
    Console.WriteLine(person.FirstName); // Prints Brent.
}
```

**Note**  
Lorsque vous exécutez une requête sans recherche indexée, elle appelle une analyse complète de la table. Dans cet exemple, nous recommandons d'avoir un [index](ql-reference.create-index.md) sur le `GovId` terrain pour optimiser les performances. Sans index activé`GovId`, les requêtes peuvent avoir une latence plus importante et peuvent également entraîner des exceptions de conflit OCC ou des délais d'expiration des transactions.

#### Utilisation des paramètres de requête
<a name="cookbook-dotnet.reading-using-params"></a>

L'exemple de code suivant utilise un paramètre de requête de type C\$1.

```
IAsyncResult<Person> result = await driver.Execute(async txn =>
{
    return await txn.Execute(txn.Query<Person>("SELECT * FROM Person WHERE FirstName = ?", "Brent"));
});

await foreach (Person person in result)
{
    Console.WriteLine(person.GovId); // Prints TOYENC486FH.
    Console.WriteLine(person.FirstName); // Prints Brent.
}
```

L'exemple de code suivant utilise plusieurs paramètres de requête de type C\$1.

```
IAsyncResult<Person> result = await driver.Execute(async txn =>
{
    return await txn.Execute(txn.Query<Person>("SELECT * FROM Person WHERE GovId = ? AND FirstName = ?", "TOYENC486FH", "Brent"));
});

await foreach (Person person in result)
{
    Console.WriteLine(person.GovId); // Prints TOYENC486FH.
    Console.WriteLine(person.FirstName); // Prints Brent.
}
```

L'exemple de code suivant utilise un tableau de paramètres de requête de type C\$1.

```
// Assumes that Person table has documents as follows:
// { "GovId": "TOYENC486FH", "FirstName" : "Brent" }
// { "GovId": "ROEE1C1AABH", "FirstName" : "Jim" }
// { "GovId": "YH844DA7LDB", "FirstName" : "Mary" }

string[] ids = {
    "TOYENC486FH",
    "ROEE1C1AABH",
    "YH844DA7LDB"
};

IAsyncResult<Person> result = await driver.Execute(async txn =>
{
    return await txn.Execute(txn.Query<Person>("SELECT * FROM Person WHERE GovId IN (?,?,?)", ids));
});

await foreach (Person person in result)
{
    Console.WriteLine(person.FirstName); // Prints Brent on first iteration.
    // Prints Jim on second iteration.
    // Prints Mary on third iteration.
}
```

L'exemple de code suivant utilise une liste C\$1 comme valeur.

```
// Assumes that Person table has document as follows:
// { "GovId": "TOYENC486FH",
//   "FirstName" : "Brent",
//   "Vehicles": [
//      { "Make": "Volkswagen",
//        "Model": "Golf"},
//      { "Make": "Honda",
//        "Model": "Civic"}
//   ]
// }
// Person class is defined as follows:
// public class Person
// {
//     public string GovId { get; set; }
//     public string FirstName { get; set; }
//     public List<Vehicle> Vehicles { get; set; }
// }
// Vehicle class is defined as follows:
// public class Vehicle
// {
//     public string Make { get; set; }
//     public string Model { get; set; }
// }

List<Vehicle> vehicles = new List<Vehicle>
{
    new Vehicle
    {
        Make = "Volkswagen",
        Model = "Golf"
    },
    new Vehicle
    {
        Make = "Honda",
        Model = "Civic"
    }
};

IAsyncResult<Person> result = await driver.Execute(async txn =>
{
    return await txn.Execute(txn.Query<Person>("SELECT * FROM Person WHERE Vehicles = ?", vehicles));
});

await foreach (Person person in result)
{
    Console.WriteLine("{");
    Console.WriteLine($"  GovId: {person.GovId},");
    Console.WriteLine($"  FirstName: {person.FirstName},");
    Console.WriteLine("  Vehicles: [");
    foreach (Vehicle vehicle in person.Vehicles)
    {
        Console.WriteLine("  {");
        Console.WriteLine($"    Make: {vehicle.Make},");
        Console.WriteLine($"    Model: {vehicle.Model},");
        Console.WriteLine("  },");
    }
    Console.WriteLine("  ]");
    Console.WriteLine("}");
    // Prints:
    // {
    //     GovId: TOYENC486FH,
    //     FirstName: Brent,
    //     Vehicles: [
    //     {
    //         Make: Volkswagen,
    //         Model: Golf
    //     },
    //     {
    //         Make: Honda,
    //         Model: Civic
    //     },
    //     ]
    // }
}
```

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.crud.reading.ion-library"></a>

------
#### [ Async ]

```
// Assumes that Person table has documents as follows:
// { "GovId": "TOYENC486FH", "FirstName" : "Brent" }

IAsyncResult result = await driver.Execute(async txn =>
{
    return await txn.Execute("SELECT * FROM Person WHERE GovId = 'TOYENC486FH'");
});

await foreach (IIonValue row in result)
{
    Console.WriteLine(row.GetField("GovId").StringValue); // Prints TOYENC486FH.
    Console.WriteLine(row.GetField("FirstName").StringValue); // Prints Brent.
}
```

------
#### [ Sync ]

```
// Assumes that Person table has documents as follows:
// { "GovId": "TOYENC486FH", "FirstName" : "Brent" }

IResult result = driver.Execute(txn =>
{
    return txn.Execute("SELECT * FROM Person WHERE GovId = 'TOYENC486FH'");
});

foreach (IIonValue row in result)
{
    Console.WriteLine(row.GetField("GovId").StringValue); // Prints TOYENC486FH.
    Console.WriteLine(row.GetField("FirstName").StringValue); // Prints Brent.
}
```

------

**Note**  
Lorsque vous exécutez une requête sans recherche indexée, elle appelle une analyse complète de la table. Dans cet exemple, nous recommandons d'avoir un [index](ql-reference.create-index.md) sur le `GovId` terrain pour optimiser les performances. Sans index activé`GovId`, les requêtes peuvent avoir une latence plus importante et peuvent également entraîner des exceptions de conflit OCC ou des délais d'expiration des transactions.

L'exemple de code suivant utilise un paramètre de requête de type Ion.

------
#### [ Async ]

```
IValueFactory valueFactory = new ValueFactory();
IIonValue ionFirstName = valueFactory.NewString("Brent");

IAsyncResult result = await driver.Execute(async txn =>
{
    return await txn.Execute("SELECT * FROM Person WHERE FirstName = ?", ionFirstName);
});

await foreach (IIonValue row in result)
{
    Console.WriteLine(row.GetField("GovId").StringValue); // Prints TOYENC486FH.
    Console.WriteLine(row.GetField("FirstName").StringValue); // Prints Brent.
}
```

------
#### [ Sync ]

```
IValueFactory valueFactory = new ValueFactory();
IIonValue ionFirstName = valueFactory.NewString("Brent");

IResult result = driver.Execute(txn =>
{
    return txn.Execute("SELECT * FROM Person WHERE FirstName = ?", ionFirstName);
});

foreach (IIonValue row in result)
{
    Console.WriteLine(row.GetField("GovId").StringValue); // Prints TOYENC486FH.
    Console.WriteLine(row.GetField("FirstName").StringValue); // Prints Brent.
}
```

------

L'exemple de code suivant utilise plusieurs paramètres de requête.

------
#### [ Async ]

```
IIonValue ionGovId = valueFactory.NewString("TOYENC486FH");
IIonValue ionFirstName = valueFactory.NewString("Brent");

IAsyncResult result = await driver.Execute(async txn =>
{
    return await txn.Execute("SELECT * FROM Person WHERE GovId = ? AND FirstName = ?", ionGovId, ionFirstName);
});

await foreach (IIonValue row in result)
{
    Console.WriteLine(row.GetField("GovId").StringValue); // Prints TOYENC486FH.
    Console.WriteLine(row.GetField("FirstName").StringValue); // Prints Brent.
}
```

------
#### [ Sync ]

```
IIonValue ionGovId = valueFactory.NewString("TOYENC486FH");
IIonValue ionFirstName = valueFactory.NewString("Brent");

IResult result = driver.Execute(txn =>
{
    return txn.Execute("SELECT * FROM Person WHERE GovId = ? AND FirstName = ?", ionGovId, ionFirstName);
});

foreach (IIonValue row in result)
{
    Console.WriteLine(row.GetField("GovId").StringValue); // Prints TOYENC486FH.
    Console.WriteLine(row.GetField("FirstName").StringValue); // Prints Brent.
}
```

------

L'exemple de code suivant utilise une liste de paramètres de requête.

------
#### [ Async ]

```
// Assumes that Person table has documents as follows:
// { "GovId": "TOYENC486FH", "FirstName" : "Brent" }
// { "GovId": "ROEE1C1AABH", "FirstName" : "Jim" }
// { "GovId": "YH844DA7LDB", "FirstName" : "Mary" }

IIonValue[] ionIds = {
    valueFactory.NewString("TOYENC486FH"),
    valueFactory.NewString("ROEE1C1AABH"),
    valueFactory.NewString("YH844DA7LDB")
};

IAsyncResult result = await driver.Execute(async txn =>
{
    return await txn.Execute("SELECT * FROM Person WHERE GovId IN (?,?,?)", ionIds);
});

await foreach (IIonValue row in result)
{
    Console.WriteLine(row.GetField("FirstName").StringValue); // Prints Brent on first iteration.
                                                              // Prints Jim on second iteration.
                                                              // Prints Mary on third iteration.
}
```

------
#### [ Sync ]

```
// Assumes that Person table has documents as follows:
// { "GovId": "TOYENC486FH", "FirstName" : "Brent" }
// { "GovId": "ROEE1C1AABH", "FirstName" : "Jim" }
// { "GovId": "YH844DA7LDB", "FirstName" : "Mary" }

IIonValue[] ionIds = {
    valueFactory.NewString("TOYENC486FH"),
    valueFactory.NewString("ROEE1C1AABH"),
    valueFactory.NewString("YH844DA7LDB")
};

IResult result = driver.Execute(txn =>
{
    return txn.Execute("SELECT * FROM Person WHERE GovId IN (?,?,?)", ionIds);
});

foreach (IIonValue row in result)
{
    Console.WriteLine(row.GetField("FirstName").StringValue); // Prints Brent on first iteration.
                                                              // Prints Jim on second iteration.
                                                              // Prints Mary on third iteration.
}
```

------

L'exemple de code suivant utilise une liste d'ions comme valeur. Pour en savoir plus sur l'utilisation des différents types d'ions, consultez[Utilisation des types de données Amazon Ion dans Amazon QLDB](driver-working-with-ion.md).

------
#### [ Async ]

```
// Assumes that Person table has document as follows:
// { "GovId": "TOYENC486FH",
//   "FirstName" : "Brent",
//   "Vehicles": [
//      { "Make": "Volkswagen",
//        "Model": "Golf"},
//      { "Make": "Honda",
//        "Model": "Civic"}
//   ]
// }

IIonValue ionVehicle1 = valueFactory.NewEmptyStruct();
ionVehicle1.SetField("Make", valueFactory.NewString("Volkswagen"));
ionVehicle1.SetField("Model", valueFactory.NewString("Golf"));

IIonValue ionVehicle2 = valueFactory.NewEmptyStruct();
ionVehicle2.SetField("Make", valueFactory.NewString("Honda"));
ionVehicle2.SetField("Model", valueFactory.NewString("Civic"));

IIonValue ionVehicles =  valueFactory.NewEmptyList();
ionVehicles.Add(ionVehicle1);
ionVehicles.Add(ionVehicle2);

IAsyncResult result = await driver.Execute(async txn =>
{
    return await txn.Execute("SELECT * FROM Person WHERE Vehicles = ?", ionVehicles);
});

await foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // Prints:
    // {
    //     GovId: "TOYENC486FN",
    //     FirstName: "Brent",
    //     Vehicles: [
    //     {
    //         Make: "Volkswagen",
    //         Model: "Golf"
    //     },
    //     {
    //         Make: "Honda",
    //         Model: "Civic"
    //     }
    //     ]
    // }
}
```

------
#### [ Sync ]

```
// Assumes that Person table has document as follows:
// { "GovId": "TOYENC486FH",
//   "FirstName" : "Brent",
//   "Vehicles": [
//      { "Make": "Volkswagen",
//        "Model": "Golf"},
//      { "Make": "Honda",
//        "Model": "Civic"}
//   ]
// }

IIonValue ionVehicle1 = valueFactory.NewEmptyStruct();
ionVehicle1.SetField("Make", valueFactory.NewString("Volkswagen"));
ionVehicle1.SetField("Model", valueFactory.NewString("Golf"));

IIonValue ionVehicle2 = valueFactory.NewEmptyStruct();
ionVehicle2.SetField("Make", valueFactory.NewString("Honda"));
ionVehicle2.SetField("Model", valueFactory.NewString("Civic"));

IIonValue ionVehicles =  valueFactory.NewEmptyList();
ionVehicles.Add(ionVehicle1);
ionVehicles.Add(ionVehicle2);

IResult result = driver.Execute(txn =>
{
    return txn.Execute("SELECT * FROM Person WHERE Vehicles = ?", ionVehicles);
});

foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // Prints:
    // {
    //     GovId: "TOYENC486FN",
    //     FirstName: "Brent",
    //     Vehicles: [
    //     {
    //         Make: "Volkswagen",
    //         Model: "Golf"
    //     },
    //     {
    //         Make: "Honda",
    //         Model: "Civic"
    //     }
    //     ]
    // }
}
```

------

### Insertion de documents
<a name="cookbook-dotnet.crud.inserting"></a>

L'exemple de code suivant insère les types de données Ion.

```
string govId = "TOYENC486FH";

Person person = new Person
{
    GovId = "TOYENC486FH",
    FirstName = "Brent"
};

await driver.Execute(async txn =>
{
    // Check if a document with GovId:TOYENC486FH exists
    // This is critical to make this transaction idempotent
    IAsyncResult<Person> result = await txn.Execute(txn.Query<Person>("SELECT * FROM Person WHERE GovId = ?", govId));

    // Check if there is a record in the cursor.
    int count = await result.CountAsync();
    if (count > 0)
    {
        // Document already exists, no need to insert
        return;
    }

    // Insert the document.
    await txn.Execute(txn.Query<Document>("INSERT INTO Person ?", person));
});
```

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.crud.inserting.ion-library"></a>

------
#### [ Async ]

```
IIonValue ionGovId = valueFactory.NewString("TOYENC486FH");

IIonValue ionPerson = valueFactory.NewEmptyStruct();
ionPerson.SetField("GovId", valueFactory.NewString("TOYENC486FH"));
ionPerson.SetField("FirstName", valueFactory.NewString("Brent"));

await driver.Execute(async txn =>
{
    // Check if a document with GovId:TOYENC486FH exists
    // This is critical to make this transaction idempotent
    IAsyncResult result = await txn.Execute("SELECT * FROM Person WHERE GovId = ?", ionGovId);

    // Check if there is a record in the cursor.
    int count = await result.CountAsync();
    if (count > 0)
    {
        // Document already exists, no need to insert
        return;
    }

    // Insert the document.
    await txn.Execute("INSERT INTO Person ?", ionPerson);
});
```

------
#### [ Sync ]

```
IIonValue ionGovId = valueFactory.NewString("TOYENC486FH");

IIonValue ionPerson = valueFactory.NewEmptyStruct();
ionPerson.SetField("GovId", valueFactory.NewString("TOYENC486FH"));
ionPerson.SetField("FirstName", valueFactory.NewString("Brent"));

driver.Execute(txn =>
{
    // Check if a document with GovId:TOYENC486FH exists
    // This is critical to make this transaction idempotent
    IResult result = txn.Execute("SELECT * FROM Person WHERE GovId = ?", ionGovId);

    // Check if there is a record in the cursor.
    int count = result.Count();
    if (count > 0)
    {
        // Document already exists, no need to insert
        return;
    }

    // Insert the document.
    txn.Execute("INSERT INTO Person ?", ionPerson);
});
```

------

Cette transaction insère un document dans le `Person` tableau. Avant l'insertion, il vérifie d'abord si le document existe déjà dans le tableau. **Cette vérification rend la transaction idempotente par nature.** Même si vous exécutez cette transaction plusieurs fois, elle ne provoquera aucun effet secondaire involontaire.

**Note**  
Dans cet exemple, nous recommandons d'avoir un index sur le `GovId` terrain pour optimiser les performances. Si l'index n'est pas activé`GovId`, les instructions peuvent avoir une latence plus importante et peuvent également entraîner des exceptions de conflit OCC ou des délais d'attente pour les transactions.

#### Insertion de plusieurs documents dans une seule déclaration
<a name="cookbook-dotnet.crud.inserting.multiple"></a>

Pour insérer plusieurs documents à l'aide d'une seule [INSERT](ql-reference.insert.md) instruction, vous pouvez transmettre un `List` paramètre C\$1 à l'instruction comme suit.

```
Person person1 = new Person
{
    FirstName = "Brent",
    GovId = "TOYENC486FH"
};

Person person2 = new Person
{
    FirstName = "Jim",
    GovId = "ROEE1C1AABH"
};

List<Person> people = new List<Person>();
people.Add(person1);
people.Add(person2);

IAsyncResult<Document> result = await driver.Execute(async txn =>
{
    return await txn.Execute(txn.Query<Document>("INSERT INTO Person ?", people));
});

await foreach (Document row in result)
{
    Console.WriteLine("{ documentId: " + row.DocumentId + " }");
    // The statement returns the created documents' ID:
    // { documentId: 6BFt5eJQDFLBW2aR8LPw42 }
    // { documentId: K5Zrcb6N3gmIEHgGhwoyKF }
}
```

##### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.crud.inserting.multiple.ion-library"></a>

Pour insérer plusieurs documents à l'aide d'une seule [INSERT](ql-reference.insert.md) instruction, vous pouvez transmettre un paramètre de type [Liste d'ions](driver-working-with-ion.md#driver-ion-list) à l'instruction comme suit.

------
#### [ Async ]

```
IIonValue ionPerson1 = valueFactory.NewEmptyStruct();
ionPerson1.SetField("FirstName", valueFactory.NewString("Brent"));
ionPerson1.SetField("GovId", valueFactory.NewString("TOYENC486FH"));

IIonValue ionPerson2 = valueFactory.NewEmptyStruct();
ionPerson2.SetField("FirstName", valueFactory.NewString("Jim"));
ionPerson2.SetField("GovId", valueFactory.NewString("ROEE1C1AABH"));

IIonValue ionPeople = valueFactory.NewEmptyList();
ionPeople.Add(ionPerson1);
ionPeople.Add(ionPerson2);

IAsyncResult result = await driver.Execute(async txn =>
{
    return await txn.Execute("INSERT INTO Person ?", ionPeople);
});

await foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // The statement returns the created documents' ID:
    // {
    //     documentId: "6BFt5eJQDFLBW2aR8LPw42"
    // }
    //
    // {
    //     documentId: "K5Zrcb6N3gmIEHgGhwoyKF"
    // }
}
```

------
#### [ Sync ]

```
IIonValue ionPerson1 = valueFactory.NewEmptyStruct();
ionPerson1.SetField("FirstName", valueFactory.NewString("Brent"));
ionPerson1.SetField("GovId", valueFactory.NewString("TOYENC486FH"));

IIonValue ionPerson2 = valueFactory.NewEmptyStruct();
ionPerson2.SetField("FirstName", valueFactory.NewString("Jim"));
ionPerson2.SetField("GovId", valueFactory.NewString("ROEE1C1AABH"));

IIonValue ionPeople = valueFactory.NewEmptyList();
ionPeople.Add(ionPerson1);
ionPeople.Add(ionPerson2);

IResult result = driver.Execute(txn =>
{
    return txn.Execute("INSERT INTO Person ?", ionPeople);
});

foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // The statement returns the created documents' ID:
    // {
    //     documentId: "6BFt5eJQDFLBW2aR8LPw42"
    // }
    //
    // {
    //     documentId: "K5Zrcb6N3gmIEHgGhwoyKF"
    // }
}
```

------

Vous ne placez pas la variable placeholder (`?`) entre crochets (`<<...>>`) lorsque vous transmettez une liste d'ions. *Dans les instructions partiQL manuelles, les crochets à double angle indiquent une collection non ordonnée appelée sac.*

### Mettre à jour des documents
<a name="cookbook-dotnet.crud.updating"></a>

```
string govId = "TOYENC486FH";
string firstName = "John";

IAsyncResult<Document> result = await driver.Execute(async txn =>
{
    return await txn.Execute(txn.Query<Document>("UPDATE Person SET FirstName = ? WHERE GovId = ?", firstName , govId));
});

await foreach (Document row in result)
{
    Console.WriteLine("{ documentId: " + row.DocumentId + " }");
    // The statement returns the updated document ID:
    // { documentId: Djg30Zoltqy5M4BFsA2jSJ }
}
```

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.crud.updating.ion-library"></a>

------
#### [ Async ]

```
IIonValue ionGovId = valueFactory.NewString("TOYENC486FH");
IIonValue ionFirstName = valueFactory.NewString("John");

IAsyncResult result = await driver.Execute(async txn =>
{
    return await txn.Execute("UPDATE Person SET FirstName = ? WHERE GovId = ?", ionFirstName , ionGovId);
});

await foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // The statement returns the updated document ID:
    // {
    //     documentId: "Djg30Zoltqy5M4BFsA2jSJ"
    // }
}
```

------
#### [ Sync ]

```
IIonValue ionGovId = valueFactory.NewString("TOYENC486FH");
IIonValue ionFirstName = valueFactory.NewString("John");

IResult result = driver.Execute(txn =>
{
    return txn.Execute("UPDATE Person SET FirstName = ? WHERE GovId = ?", ionFirstName , ionGovId);
});

foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // The statement returns the updated document ID:
    // {
    //     documentId: "Djg30Zoltqy5M4BFsA2jSJ"
    // }
}
```

------

**Note**  
Dans cet exemple, nous recommandons d'avoir un index sur le `GovId` terrain pour optimiser les performances. Si l'index n'est pas activé`GovId`, les instructions peuvent avoir une latence plus importante et peuvent également entraîner des exceptions de conflit OCC ou des délais d'attente pour les transactions.

### Supprimer des documents
<a name="cookbook-dotnet.crud.deleting"></a>

```
string govId = "TOYENC486FH";

IAsyncResult<Document> result = await driver.Execute(async txn =>
{
    return await txn.Execute(txn.Query<Document>("DELETE FROM Person WHERE GovId = ?", govId));
});

await foreach (Document row in result)
{
    Console.WriteLine("{ documentId: " + row.DocumentId + " }");
    // The statement returns the updated document ID:
    // { documentId: Djg30Zoltqy5M4BFsA2jSJ }
}
```

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.crud.deleting.ion-library"></a>

------
#### [ Async ]

```
IIonValue ionGovId = valueFactory.NewString("TOYENC486FH");

IAsyncResult result = await driver.Execute(async txn =>
{
    return await txn.Execute("DELETE FROM Person WHERE GovId = ?", ionGovId);
});

await foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // The statement returns the deleted document ID:
    // {
    //     documentId: "Djg30Zoltqy5M4BFsA2jSJ"
    // }
}
```

------
#### [ Sync ]

```
IIonValue ionGovId = valueFactory.NewString("TOYENC486FH");

IResult result = driver.Execute(txn =>
{
    return txn.Execute("DELETE FROM Person WHERE GovId = ?", ionGovId);
});

foreach (IIonValue row in result)
{
    Console.WriteLine(row.ToPrettyString());
    // The statement returns the deleted document ID:
    // {
    //     documentId: "Djg30Zoltqy5M4BFsA2jSJ"
    // }
}
```

------

**Note**  
Dans cet exemple, nous recommandons d'avoir un index sur le `GovId` terrain pour optimiser les performances. Si l'index n'est pas activé`GovId`, les instructions peuvent avoir une latence plus importante et peuvent également entraîner des exceptions de conflit OCC ou des délais d'attente pour les transactions.

### Exécution de plusieurs instructions dans une transaction
<a name="cookbook-dotnet.crud.multi-statement"></a>

```
// This code snippet is intentionally trivial. In reality you wouldn't do this because you'd
// set your UPDATE to filter on vin and insured, and check if you updated something or not.
public static async Task<bool> InsureVehicle(IAsyncQldbDriver driver, string vin)
{
    return await driver.Execute(async txn =>
    {
        // Check if the vehicle is insured.
        Amazon.QLDB.Driver.Generic.IAsyncResult<Vehicle> result = await txn.Execute(
            txn.Query<Vehicle>("SELECT insured FROM Vehicles WHERE vin = ? AND insured = FALSE", vin));

        if (await result.CountAsync() > 0)
        {
            // If the vehicle is not insured, insure it.
            await txn.Execute(
                txn.Query<Document>("UPDATE Vehicles SET insured = TRUE WHERE vin = ?", vin));
            return true;
        }
        return false;
    });
}
```

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.crud.multi-statement.ion-library"></a>

------
#### [ Async ]

```
// This code snippet is intentionally trivial. In reality you wouldn't do this because you'd
// set your UPDATE to filter on vin and insured, and check if you updated something or not.
public static async Task<bool> InsureVehicle(IAsyncQldbDriver driver, string vin)
{
    ValueFactory valueFactory = new ValueFactory();
    IIonValue ionVin = valueFactory.NewString(vin);

    return await driver.Execute(async txn =>
    {
        // Check if the vehicle is insured.
        Amazon.QLDB.Driver.IAsyncResult result = await txn.Execute(
            "SELECT insured FROM Vehicles WHERE vin = ? AND insured = FALSE", ionVin);

        if (await result.CountAsync() > 0)
        {
            // If the vehicle is not insured, insure it.
            await txn.Execute(
                "UPDATE Vehicles SET insured = TRUE WHERE vin = ?", ionVin);
            return true;
        }
        return false;
    });
}
```

------

### Logique des nouvelles tentatives
<a name="cookbook-dotnet.crud.retry-logic"></a>

Pour plus d'informations sur la logique de nouvelle tentative intégrée au pilote, consultez[Comprendre la politique de nouvelle tentative avec le pilote dans Amazon QLDB](driver-retry-policy.md).

### Mettre en œuvre des contraintes d'unicité
<a name="cookbook-dotnet.crud.uniqueness-constraints"></a>

QLDB ne prend pas en charge les index uniques, mais vous pouvez implémenter ce comportement dans votre application.

Supposons que vous souhaitiez implémenter une contrainte d'unicité sur le `GovId` champ de la `Person` table. Pour ce faire, vous pouvez écrire une transaction qui effectue les opérations suivantes :

1. Affirme que le tableau ne contient aucun document existant avec une valeur spécifiée`GovId`.

1. Insérez le document si l'assertion est acceptée.

Si une transaction concurrente passe simultanément l'assertion, une seule des transactions sera validée avec succès. L'autre transaction échouera en raison d'une exception de conflit OCC.

L'exemple de code suivant montre comment implémenter cette logique de contrainte d'unicité.

```
string govId = "TOYENC486FH";

Person person = new Person
{
    GovId = "TOYENC486FH",
    FirstName = "Brent"
};

await driver.Execute(async txn =>
{
    // Check if a document with GovId:TOYENC486FH exists
    // This is critical to make this transaction idempotent
    IAsyncResult<Person> result = await txn.Execute(txn.Query<Person>("SELECT * FROM Person WHERE GovId = ?", govId));

    // Check if there is a record in the cursor.
    int count = await result.CountAsync();
    if (count > 0)
    {
        // Document already exists, no need to insert
        return;
    }

    // Insert the document.
    await txn.Execute(txn.Query<Document>("INSERT INTO Person ?", person));
});
```

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.crud.uniqueness.ion-library"></a>

------
#### [ Async ]

```
IIonValue ionGovId = valueFactory.NewString("TOYENC486FH");

IIonValue ionPerson = valueFactory.NewEmptyStruct();
ionPerson.SetField("GovId", valueFactory.NewString("TOYENC486FH"));
ionPerson.SetField("FirstName", valueFactory.NewString("Brent"));

await driver.Execute(async txn =>
{
    // Check if a document with GovId:TOYENC486FH exists
    // This is critical to make this transaction idempotent
    IAsyncResult result = await txn.Execute("SELECT * FROM Person WHERE GovId = ?", ionGovId);

    // Check if there is a record in the cursor.
    int count = await result.CountAsync();
    if (count > 0)
    {
        // Document already exists, no need to insert
        return;
    }

    // Insert the document.
    await txn.Execute("INSERT INTO Person ?", ionPerson);
});
```

------
#### [ Sync ]

```
IIonValue ionGovId = valueFactory.NewString("TOYENC486FH");

IIonValue ionPerson = valueFactory.NewEmptyStruct();
ionPerson.SetField("GovId", valueFactory.NewString("TOYENC486FH"));
ionPerson.SetField("FirstName", valueFactory.NewString("Brent"));

driver.Execute(txn =>
{
    // Check if a document with GovId:TOYENC486FH exists
    // This is critical to make this transaction idempotent
    IResult result = txn.Execute("SELECT * FROM Person WHERE GovId = ?", ionGovId);

    // Check if there is a record in the cursor.
    int count = result.Count();
    if (count > 0)
    {
        // Document already exists, no need to insert
        return;
    }

    // Insert the document.
    txn.Execute("INSERT INTO Person ?", ionPerson);
});
```

------

**Note**  
Dans cet exemple, nous recommandons d'avoir un index sur le `GovId` terrain pour optimiser les performances. Si l'index n'est pas activé`GovId`, les instructions peuvent avoir une latence plus importante et peuvent également entraîner des exceptions de conflit OCC ou des délais d'attente pour les transactions.

## Travailler avec Amazon Ion
<a name="cookbook-dotnet.ion"></a>

Il existe plusieurs méthodes pour traiter les données Amazon Ion dans QLDB. Vous pouvez utiliser la [bibliothèque Ion](https://github.com/amzn/ion-dotnet) pour créer et modifier des valeurs d'ions. Vous pouvez également utiliser le mappeur [d'objets Ion pour mapper](https://github.com/amzn/ion-object-mapper-dotnet) de *vieux objets CLR* (POCO) en C\$1 vers et depuis des valeurs Ion. La version 1.3.0 du pilote QLDB pour .NET intègre la prise en charge du mappeur d'objets Ion.

Les sections suivantes fournissent des exemples de code de traitement de données ioniques à l'aide des deux techniques.

**Contents**
+ [Importation du module Ion](#cookbook-dotnet.ion.import)
+ [Création de types d'ions](#cookbook-dotnet.ion.creating-types)
+ [Obtenir un dump binaire d'ions](#cookbook-dotnet.ion.getting-binary)
+ [Obtenir un vidage de texte Ion](#cookbook-dotnet.ion.getting-text)

### Importation du module Ion
<a name="cookbook-dotnet.ion.import"></a>

```
using Amazon.IonObjectMapper;
```

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.ion.import.ion-library"></a>

```
using Amazon.IonDotnet.Builders;
```

### Création de types d'ions
<a name="cookbook-dotnet.ion.creating-types"></a>

L'exemple de code suivant montre comment créer des valeurs Ion à partir d'objets C\$1 à l'aide du mappeur d'objets Ion.

```
// Assumes that Person class is defined as follows:
// public class Person
// {
//     public string FirstName { get; set; }
//     public int Age { get; set; }
// }

// Initialize the Ion Object Mapper
IonSerializer ionSerializer = new IonSerializer();

// The C# object to be serialized
Person person = new Person
{
    FirstName = "John",
    Age = 13
};

// Serialize the C# object into stream using the Ion Object Mapper
Stream stream = ionSerializer.Serialize(person);

// Load will take in stream and return a datagram; a top level container of Ion values.
IIonValue ionDatagram = IonLoader.Default.Load(stream);

// To get the Ion value within the datagram, we call GetElementAt(0).
IIonValue ionPerson = ionDatagram.GetElementAt(0);

Console.WriteLine(ionPerson.GetField("firstName").StringValue);
Console.WriteLine(ionPerson.GetField("age").IntValue);
```

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.ion.creating-types.ion-library"></a>

Les exemples de code suivants montrent les deux manières de créer des valeurs d'ions à l'aide de la bibliothèque d'ions.

**Utilisation de `ValueFactory`**

```
using Amazon.IonDotnet.Tree;
using Amazon.IonDotnet.Tree.Impl;

IValueFactory valueFactory = new ValueFactory();

IIonValue ionPerson = valueFactory.NewEmptyStruct();
ionPerson.SetField("firstName", valueFactory.NewString("John"));
ionPerson.SetField("age", valueFactory.NewInt(13));

Console.WriteLine(ionPerson.GetField("firstName").StringValue);
Console.WriteLine(ionPerson.GetField("age").IntValue);
```

**Utilisation de `IonLoader`**

```
using Amazon.IonDotnet.Builders;
using Amazon.IonDotnet.Tree;

// Load will take in Ion text and return a datagram; a top level container of Ion values.
IIonValue ionDatagram = IonLoader.Default.Load("{firstName: \"John\", age: 13}");

// To get the Ion value within the datagram, we call GetElementAt(0).
IIonValue ionPerson = ionDatagram.GetElementAt(0);

Console.WriteLine(ionPerson.GetField("firstName").StringValue);
Console.WriteLine(ionPerson.GetField("age").IntValue);
```

### Obtenir un dump binaire d'ions
<a name="cookbook-dotnet.ion.getting-binary"></a>

```
// Initialize the Ion Object Mapper with Ion binary serialization format
IonSerializer ionSerializer = new IonSerializer(new IonSerializationOptions
{
    Format = IonSerializationFormat.BINARY
});

// The C# object to be serialized
Person person = new Person
{
    FirstName = "John",
    Age = 13
};

MemoryStream stream = (MemoryStream) ionSerializer.Serialize(person);
Console.WriteLine(BitConverter.ToString(stream.ToArray()));
```

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.ion.getting-binary.ion-library"></a>

```
// ionObject is an Ion struct
MemoryStream stream = new MemoryStream();
using (var writer = IonBinaryWriterBuilder.Build(stream))
{
    ionObject.WriteTo(writer);
    writer.Finish();
}

Console.WriteLine(BitConverter.ToString(stream.ToArray()));
```

### Obtenir un vidage de texte Ion
<a name="cookbook-dotnet.ion.getting-text"></a>

```
// Initialize the Ion Object Mapper
IonSerializer ionSerializer = new IonSerializer(new IonSerializationOptions
{
    Format = IonSerializationFormat.TEXT
});

// The C# object to be serialized
Person person = new Person
{
    FirstName = "John",
    Age = 13
};

MemoryStream stream = (MemoryStream) ionSerializer.Serialize(person);
Console.WriteLine(System.Text.Encoding.UTF8.GetString(stream.ToArray()));
```

#### Utilisation de la bibliothèque Ion
<a name="cookbook-dotnet.ion.getting-text.ion-library"></a>

```
// ionObject is an Ion struct
StringWriter sw = new StringWriter();
using (var writer = IonTextWriterBuilder.Build(sw))
{
    ionObject.WriteTo(writer);
    writer.Finish();
}

Console.WriteLine(sw.ToString());
```

Pour plus d'informations sur l'utilisation d'Ion, consultez la [documentation Amazon Ion](http://amzn.github.io/ion-docs/) sur GitHub. Pour d'autres exemples de code relatifs à l'utilisation d'Ion dans QLDB, consultez. [Utilisation des types de données Amazon Ion dans Amazon QLDB](driver-working-with-ion.md)