

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Driver Amazon QLDB untuk .NET - Referensi buku masak
<a name="driver-cookbook-dotnet"></a>

**penting**  
Pemberitahuan akhir dukungan: Pelanggan yang ada akan dapat menggunakan Amazon QLDB hingga akhir dukungan pada 07/31/2025. Untuk detail selengkapnya, lihat [Memigrasi Buku Besar QLDB Amazon ke Amazon](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/) Aurora PostgreSQL.

Panduan referensi ini menunjukkan kasus penggunaan umum driver QLDB Amazon untuk.NET. Ini memberikan contoh kode C \$1 yang menunjukkan cara menggunakan driver untuk menjalankan operasi dasar *membuat, membaca, memperbarui, dan menghapus* (CRUD). Ini juga mencakup contoh kode untuk memproses data Amazon Ion. Selain itu, panduan ini menyoroti praktik terbaik untuk membuat transaksi idempoten dan menerapkan kendala keunikan.

**catatan**  
Topik ini memberikan contoh kode pemrosesan data Amazon Ion menggunakan [pemetaan objek Ion secara](https://github.com/amzn/ion-object-mapper-dotnet) default. QLDB memperkenalkan pemetaan objek Ion di driver .NET versi 1.3.0. Jika berlaku, topik ini juga memberikan contoh kode menggunakan [pustaka Ion](https://github.com/amzn/ion-dotnet) standar sebagai alternatif. Untuk mempelajari selengkapnya, lihat [Bekerja dengan Amazon Ion](#cookbook-dotnet.ion).

**Contents**
+ [Mengimpor driver](#cookbook-dotnet.importing)
+ [Membuat instantiasi pengemudi](#cookbook-dotnet.instantiating)
+ [Operasi CRUD](#cookbook-dotnet.crud)
  + [Membuat tabel](#cookbook-dotnet.crud.creating-tables)
  + [Membuat indeks](#cookbook-dotnet.crud.creating-indexes)
  + [Membaca dokumen](#cookbook-dotnet.crud.reading)
    + [Menggunakan parameter kueri](#cookbook-dotnet.reading-using-params)
  + [Memasukkan dokumen](#cookbook-dotnet.crud.inserting)
    + [Menyisipkan beberapa dokumen dalam satu pernyataan](#cookbook-dotnet.crud.inserting.multiple)
  + [Memperbarui dokumen](#cookbook-dotnet.crud.updating)
  + [Menghapus dokumen](#cookbook-dotnet.crud.deleting)
  + [Menjalankan beberapa pernyataan dalam transaksi](#cookbook-dotnet.crud.multi-statement)
  + [Logika coba lagi](#cookbook-dotnet.crud.retry-logic)
  + [Menerapkan kendala keunikan](#cookbook-dotnet.crud.uniqueness-constraints)
+ [Bekerja dengan Amazon Ion](#cookbook-dotnet.ion)
  + [Mengimpor modul Ion](#cookbook-dotnet.ion.import)
  + [Membuat tipe Ion](#cookbook-dotnet.ion.creating-types)
  + [Mendapatkan dump biner Ion](#cookbook-dotnet.ion.getting-binary)
  + [Mendapatkan dump teks Ion](#cookbook-dotnet.ion.getting-text)

## Mengimpor driver
<a name="cookbook-dotnet.importing"></a>

Contoh kode berikut mengimpor driver.

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

### Menggunakan perpustakaan Ion
<a name="cookbook-dotnet.importing.ion-library"></a>

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

## Membuat instantiasi pengemudi
<a name="cookbook-dotnet.instantiating"></a>

Contoh kode berikut membuat instance driver yang terhubung ke nama buku besar tertentu menggunakan pengaturan default.

------
#### [ 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();
```

------

### Menggunakan perpustakaan 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();
```

------

## Operasi CRUD
<a name="cookbook-dotnet.crud"></a>

QLDB *menjalankan operasi create, read, update, and* delete (CRUD) sebagai bagian dari transaksi.

**Awas**  
Sebagai praktik terbaik, buat transaksi tulis Anda benar-benar idempoten.

**Membuat transaksi idempoten**

Kami menyarankan Anda membuat transaksi tulis idempoten untuk menghindari efek samping yang tidak terduga dalam kasus percobaan ulang. Transaksi adalah *idempoten* jika dapat berjalan beberapa kali dan menghasilkan hasil yang identik setiap kali.

Misalnya, pertimbangkan transaksi yang menyisipkan dokumen ke dalam tabel bernama`Person`. Transaksi harus terlebih dahulu memeriksa apakah dokumen sudah ada dalam tabel atau tidak. Tanpa pemeriksaan ini, tabel mungkin berakhir dengan dokumen duplikat.

Misalkan QLDB berhasil melakukan transaksi di sisi server, tetapi waktu klien habis sambil menunggu respons. Jika transaksi tidak idempoten, dokumen yang sama dapat dimasukkan lebih dari sekali dalam kasus percobaan ulang.

**Menggunakan indeks untuk menghindari pemindaian tabel penuh**

Kami juga menyarankan Anda menjalankan pernyataan dengan klausa `WHERE` predikat menggunakan operator *kesetaraan* pada bidang yang diindeks atau ID dokumen; misalnya, atau. `WHERE indexedField = 123` `WHERE indexedField IN (456, 789)` *Tanpa pencarian yang diindeks ini, QLDB perlu melakukan pemindaian tabel, yang dapat menyebabkan batas waktu transaksi atau konflik kontrol konkurensi optimis (OCC).*

Untuk informasi lebih lanjut tentang OCC, lihat[Model konkurensi QLDB Amazon](concurrency.md).

**Transaksi yang dibuat secara implisit**

[Amazon.qldb.driver. ](https://amazon-qldb-docs.s3.amazonaws.com/drivers/dotnet/1.4.1/api/Amazon.QLDB.Driver.IQldbDriver.html)IQldb[Metode Driver.Execute menerima fungsi lambda yang menerima instance Amazon.qldb.driver. TransactionExecutor](https://amazon-qldb-docs.s3.amazonaws.com/drivers/dotnet/1.4.1/api/Amazon.QLDB.Driver.TransactionExecutor.html), yang dapat Anda gunakan untuk menjalankan pernyataan. Contoh `TransactionExecutor` membungkus transaksi yang dibuat secara implisit.

Anda dapat menjalankan pernyataan dalam fungsi lambda dengan menggunakan `Execute` metode pelaksana transaksi. Pengemudi secara implisit melakukan transaksi saat fungsi lambda kembali.

Bagian berikut menunjukkan cara menjalankan operasi CRUD dasar, menentukan logika coba ulang kustom, dan menerapkan kendala keunikan.

**Contents**
+ [Membuat tabel](#cookbook-dotnet.crud.creating-tables)
+ [Membuat indeks](#cookbook-dotnet.crud.creating-indexes)
+ [Membaca dokumen](#cookbook-dotnet.crud.reading)
  + [Menggunakan parameter kueri](#cookbook-dotnet.reading-using-params)
+ [Memasukkan dokumen](#cookbook-dotnet.crud.inserting)
  + [Menyisipkan beberapa dokumen dalam satu pernyataan](#cookbook-dotnet.crud.inserting.multiple)
+ [Memperbarui dokumen](#cookbook-dotnet.crud.updating)
+ [Menghapus dokumen](#cookbook-dotnet.crud.deleting)
+ [Menjalankan beberapa pernyataan dalam transaksi](#cookbook-dotnet.crud.multi-statement)
+ [Logika coba lagi](#cookbook-dotnet.crud.retry-logic)
+ [Menerapkan kendala keunikan](#cookbook-dotnet.crud.uniqueness-constraints)

### Membuat tabel
<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 }
}
```

------

#### Menggunakan perpustakaan 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"
    // }
}
```

------

### Membuat indeks
<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 }
}
```

------

#### Menggunakan perpustakaan 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"
    // }
}
```

------

### Membaca dokumen
<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.
}
```

**catatan**  
Saat Anda menjalankan kueri tanpa pencarian yang diindeks, itu akan memanggil pemindaian tabel lengkap. Dalam contoh ini, kami merekomendasikan memiliki [indeks](ql-reference.create-index.md) di `GovId` lapangan untuk mengoptimalkan kinerja. Tanpa indeks aktif`GovId`, kueri dapat memiliki lebih banyak latensi dan juga dapat menyebabkan pengecualian konflik OCC atau batas waktu transaksi.

#### Menggunakan parameter kueri
<a name="cookbook-dotnet.reading-using-params"></a>

Contoh kode berikut menggunakan parameter query tipe 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.
}
```

Contoh kode berikut menggunakan beberapa parameter kueri tipe 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.
}
```

Contoh kode berikut menggunakan array parameter query tipe 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.
}
```

Contoh kode berikut menggunakan daftar C \$1 sebagai nilai.

```
// 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
    //     },
    //     ]
    // }
}
```

#### Menggunakan perpustakaan 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.
}
```

------

**catatan**  
Saat Anda menjalankan kueri tanpa pencarian yang diindeks, itu akan memanggil pemindaian tabel lengkap. Dalam contoh ini, kami merekomendasikan memiliki [indeks](ql-reference.create-index.md) di `GovId` lapangan untuk mengoptimalkan kinerja. Tanpa indeks aktif`GovId`, kueri dapat memiliki lebih banyak latensi dan juga dapat menyebabkan pengecualian konflik OCC atau batas waktu transaksi.

Contoh kode berikut menggunakan parameter query tipe 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.
}
```

------

Contoh kode berikut menggunakan beberapa parameter query.

------
#### [ 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.
}
```

------

Contoh kode berikut menggunakan daftar parameter query.

------
#### [ 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.
}
```

------

Contoh kode berikut menggunakan daftar Ion sebagai nilai. Untuk mempelajari lebih lanjut tentang menggunakan tipe Ion yang berbeda, lihat[Bekerja dengan tipe data Amazon Ion di 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"
    //     }
    //     ]
    // }
}
```

------

### Memasukkan dokumen
<a name="cookbook-dotnet.crud.inserting"></a>

Contoh kode berikut menyisipkan tipe data 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));
});
```

#### Menggunakan perpustakaan 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);
});
```

------

Transaksi ini memasukkan dokumen ke dalam `Person` tabel. Sebelum memasukkan, pertama-tama memeriksa apakah dokumen sudah ada di tabel. **Pemeriksaan ini membuat transaksi idempoten di alam.** Bahkan jika Anda menjalankan transaksi ini beberapa kali, itu tidak akan menyebabkan efek samping yang tidak diinginkan.

**catatan**  
Dalam contoh ini, kami merekomendasikan memiliki indeks di `GovId` lapangan untuk mengoptimalkan kinerja. Tanpa indeks aktif`GovId`, pernyataan dapat memiliki lebih banyak latensi dan juga dapat menyebabkan pengecualian konflik OCC atau batas waktu transaksi.

#### Menyisipkan beberapa dokumen dalam satu pernyataan
<a name="cookbook-dotnet.crud.inserting.multiple"></a>

Untuk menyisipkan beberapa dokumen dengan menggunakan satu [INSERT](ql-reference.insert.md) pernyataan, Anda dapat meneruskan `List` parameter C\$1 ke pernyataan sebagai berikut.

```
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 }
}
```

##### Menggunakan perpustakaan Ion
<a name="cookbook-dotnet.crud.inserting.multiple.ion-library"></a>

Untuk menyisipkan beberapa dokumen dengan menggunakan [INSERT](ql-reference.insert.md) pernyataan tunggal, Anda dapat meneruskan parameter tipe [Daftar Ion](driver-working-with-ion.md#driver-ion-list) ke pernyataan sebagai berikut.

------
#### [ 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"
    // }
}
```

------

Anda tidak melampirkan variabel placeholder (`?`) dalam tanda kurung sudut ganda (`<<...>>`) saat melewati daftar Ion. *Dalam pernyataan PartiQL manual, tanda kurung sudut ganda menunjukkan koleksi tidak berurutan yang dikenal sebagai tas.*

### Memperbarui dokumen
<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 }
}
```

#### Menggunakan perpustakaan 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"
    // }
}
```

------

**catatan**  
Dalam contoh ini, kami merekomendasikan memiliki indeks di `GovId` lapangan untuk mengoptimalkan kinerja. Tanpa indeks aktif`GovId`, pernyataan dapat memiliki lebih banyak latensi dan juga dapat menyebabkan pengecualian konflik OCC atau batas waktu transaksi.

### Menghapus dokumen
<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 }
}
```

#### Menggunakan perpustakaan 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"
    // }
}
```

------

**catatan**  
Dalam contoh ini, kami merekomendasikan memiliki indeks di `GovId` lapangan untuk mengoptimalkan kinerja. Tanpa indeks aktif`GovId`, pernyataan dapat memiliki lebih banyak latensi dan juga dapat menyebabkan pengecualian konflik OCC atau batas waktu transaksi.

### Menjalankan beberapa pernyataan dalam transaksi
<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;
    });
}
```

#### Menggunakan perpustakaan 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;
    });
}
```

------

### Logika coba lagi
<a name="cookbook-dotnet.crud.retry-logic"></a>

Untuk informasi tentang logika coba ulang bawaan pengemudi, lihat[Memahami kebijakan coba lagi dengan pengemudi di Amazon QLDB](driver-retry-policy.md).

### Menerapkan kendala keunikan
<a name="cookbook-dotnet.crud.uniqueness-constraints"></a>

QLDB tidak mendukung indeks unik, tetapi Anda dapat menerapkan perilaku ini dalam aplikasi Anda.

Misalkan Anda ingin menerapkan kendala keunikan pada `GovId` bidang dalam tabel. `Person` Untuk melakukan ini, Anda dapat menulis transaksi yang melakukan hal berikut:

1. Tegaskan bahwa tabel tidak memiliki dokumen yang ada dengan yang ditentukan`GovId`.

1. Masukkan dokumen jika pernyataan lolos.

Jika transaksi yang bersaing secara bersamaan melewati pernyataan, hanya satu transaksi yang akan berhasil dilakukan. Transaksi lainnya akan gagal dengan pengecualian konflik OCC.

Contoh kode berikut menunjukkan bagaimana menerapkan logika kendala keunikan ini.

```
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));
});
```

#### Menggunakan perpustakaan 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);
});
```

------

**catatan**  
Dalam contoh ini, kami merekomendasikan memiliki indeks di `GovId` lapangan untuk mengoptimalkan kinerja. Tanpa indeks aktif`GovId`, pernyataan dapat memiliki lebih banyak latensi dan juga dapat menyebabkan pengecualian konflik OCC atau batas waktu transaksi.

## Bekerja dengan Amazon Ion
<a name="cookbook-dotnet.ion"></a>

Ada beberapa cara untuk memproses data Amazon Ion di QLDB. Anda dapat menggunakan [perpustakaan Ion](https://github.com/amzn/ion-dotnet) untuk membuat dan memodifikasi nilai Ion. Atau, Anda dapat menggunakan [pemetaan objek Ion untuk memetakan objek](https://github.com/amzn/ion-object-mapper-dotnet) *CLR lama biasa* C\$1 (POCO) ke dan dari nilai Ion. Versi 1.3.0 dari driver QLDB untuk.NET memperkenalkan dukungan untuk pemetaan objek Ion.

Bagian berikut memberikan contoh kode pemrosesan data Ion menggunakan kedua teknik.

**Contents**
+ [Mengimpor modul Ion](#cookbook-dotnet.ion.import)
+ [Membuat tipe Ion](#cookbook-dotnet.ion.creating-types)
+ [Mendapatkan dump biner Ion](#cookbook-dotnet.ion.getting-binary)
+ [Mendapatkan dump teks Ion](#cookbook-dotnet.ion.getting-text)

### Mengimpor modul Ion
<a name="cookbook-dotnet.ion.import"></a>

```
using Amazon.IonObjectMapper;
```

#### Menggunakan perpustakaan Ion
<a name="cookbook-dotnet.ion.import.ion-library"></a>

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

### Membuat tipe Ion
<a name="cookbook-dotnet.ion.creating-types"></a>

Contoh kode berikut menunjukkan cara membuat nilai Ion dari objek C\$1 menggunakan pemetaan objek 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);
```

#### Menggunakan perpustakaan Ion
<a name="cookbook-dotnet.ion.creating-types.ion-library"></a>

Contoh kode berikut menunjukkan dua cara untuk membuat nilai Ion menggunakan perpustakaan Ion.

**Menggunakan `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);
```

**Menggunakan `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);
```

### Mendapatkan dump biner Ion
<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()));
```

#### Menggunakan perpustakaan 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()));
```

### Mendapatkan dump teks 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()));
```

#### Menggunakan perpustakaan 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());
```

Untuk informasi selengkapnya tentang bekerja dengan Ion, lihat [dokumentasi Amazon Ion](http://amzn.github.io/ion-docs/) di GitHub. Untuk contoh kode lebih lanjut tentang bekerja dengan Ion di QLDB, lihat. [Bekerja dengan tipe data Amazon Ion di Amazon QLDB](driver-working-with-ion.md)