Hello World C#

Questo esempio di codice è un'applicazione "Hello World" scritta in C#. L'esempio illustra come completare le attività seguenti:

  • Configura l'autenticazione
  • Connetti a un'istanza Bigtable
  • Crea una nuova tabella.
  • Scrivi i dati nella tabella.
  • Leggere i dati.
  • Elimina la tabella.

Configura l'autenticazione

Per utilizzare gli esempi .NET in questa pagina da un ambiente di sviluppo locale, installa e inizializza gcloud CLI, quindi configura Credenziali predefinite dell'applicazione con le tue credenziali utente.

  1. Installa Google Cloud CLI.
  2. Per initialize gcloud CLI, esegui questo comando:

    gcloud init
  3. Crea credenziali di autenticazione locali per il tuo Account Google:

    gcloud auth application-default login

Per ulteriori informazioni, consulta Configura l'autenticazione per un ambiente di sviluppo locale.

Esecuzione dell'esempio

Questo codice comunica con Bigtable utilizzando le librerie dell'API C# Admin e dell'API C# Data nelle librerie client di Google Cloud per .NET.

Per eseguire questo programma di esempio, segui le istruzioni di esempi di.NET Bigtable su GitHub. Completa i passaggi Creazione ed esecuzione e Avvio rapido per creare risorse da utilizzare nella tua applicazione Hello World. Assicurati di modificare il file HelloWorld.cs per aggiungere i nomi delle risorse che crei.

Utilizzo delle librerie client di Cloud con Bigtable

L'applicazione di esempio si connette a Bigtable e dimostra alcune operazioni semplici.

Connessione a Bigtable

Per iniziare, crea due oggetti client da utilizzare per la connessione a Bigtable. Le API C# Admin BigtableTableAdminClient consentono di creare ed eliminare istanze e tabelle. Le API di dati C# BigtableClient consentono di leggere e scrivere i dati delle tabelle.

// BigtableTableAdminClient API lets us create, manage and delete tables.
BigtableTableAdminClient bigtableTableAdminClient = BigtableTableAdminClient.Create();

// BigtableClient API lets us read and write to a table.
BigtableClient bigtableClient = BigtableClient.Create();

Creazione di una tabella

Chiama il metodo CreateTable() nella classe BigtableTableAdminClient per generare un oggetto Table che archivia i saluti "helloworld". La tabella ha una singola famiglia di colonne che conserva una versione di ciascun valore.

// Create a table with a single column family.
Console.WriteLine($"Create new table: {tableId} with column family: {columnFamily}, instance: {instanceId}");

// Check whether a table with given TableName already exists.
if (!TableExist(bigtableTableAdminClient))
{
    bigtableTableAdminClient.CreateTable(
        new InstanceName(projectId, instanceId),
        tableId,
        new Table
        {
            Granularity = Table.Types.TimestampGranularity.Millis,
            ColumnFamilies =
            {
                {
                    columnFamily, new ColumnFamily
                    {
                        GcRule = new GcRule
                        {
                            MaxNumVersions = 1
                        }
                    }
                }
            }
        });
    // Confirm that table was created successfully.
    Console.WriteLine(TableExist(bigtableTableAdminClient)
        ? $"Table {tableId} created successfully\n"
        : $"There was a problem creating a table {tableId}");
}
else
{
    Console.WriteLine($"Table: {tableId} already exists");
}

Scrittura di righe in una tabella

Utilizza l'array di stringhe s_greetings[], che contiene tre semplici saluti, come origine di dati per scrivere nella tabella. Scrivi una singola riga nella tabella utilizzando MutateRow(). Quindi, esegui il loop del resto dell'array per creare un oggetto MutateRowsRequest che contenga una voce per ogni saluto. Effettua la richiesta di scrivere tutte le voci contemporaneamente con MutateRows(). Quindi, esegui il loop della risposta restituita per controllare il codice di stato di ogni voce per assicurarti che sia stata scritta correttamente.

// Initialize Google.Cloud.Bigtable.V2.TableName object.
Google.Cloud.Bigtable.Common.V2.TableName tableName = new Google.Cloud.Bigtable.Common.V2.TableName(projectId, instanceId, tableId);

// Write some rows
/* Each row has a unique row key.

       Note: This example uses sequential numeric IDs for simplicity, but
       this can result in poor performance in a production application.
       Since rows are stored in sorted order by key, sequential keys can
       result in poor distribution of operations across nodes.

       For more information about how to design a Bigtable schema for the
       best performance, see the documentation:

       https://cloud.google.com/bigtable/docs/schema-design */

Console.WriteLine($"Write some greetings to the table {tableId}");

// Insert 1 row using MutateRow()
s_greetingIndex = 0;
try
{
    bigtableClient.MutateRow(tableName, rowKeyPrefix + s_greetingIndex, MutationBuilder());
    Console.WriteLine($"\tGreeting:   -- {s_greetings[s_greetingIndex],-18}-- written successfully");
}
catch (Exception ex)
{
    Console.WriteLine($"\tFailed to write greeting: --{s_greetings[s_greetingIndex]}");
    Console.WriteLine(ex.Message);
    throw;
}

// Insert multiple rows using MutateRows()
// Build a MutateRowsRequest (contains table name and a collection of entries).
MutateRowsRequest request = new MutateRowsRequest
{
    TableNameAsTableName = tableName
};

s_mapToOriginalGreetingIndex = new List<int>();
while (++s_greetingIndex < s_greetings.Length)
{
    s_mapToOriginalGreetingIndex.Add(s_greetingIndex);
    // Build an entry for every greeting (consists of rowkey and a collection of mutations).
    string rowKey = rowKeyPrefix + s_greetingIndex;
    request.Entries.Add(Mutations.CreateEntry(rowKey, MutationBuilder()));
}

// Make the request to write multiple rows.
MutateRowsResponse response = bigtableClient.MutateRows(request);

// Check the status code of each entry to ensure that it was written successfully.
foreach (MutateRowsResponse.Types.Entry entry in response.Entries)
{
    s_greetingIndex = s_mapToOriginalGreetingIndex[(int)entry.Index];
    if (entry.Status.Code == 0)
    {
        Console.WriteLine($"\tGreeting:   -- {s_greetings[s_greetingIndex],-18}-- written successfully");
    }
    else
    {
        Console.WriteLine($"\tFailed to write greeting: --{s_greetings[s_greetingIndex]}");
        Console.WriteLine(entry.Status.Message);
    }
}

Mutation MutationBuilder() =>
    Mutations.SetCell(columnFamily, columnName, s_greetings[s_greetingIndex], new BigtableVersion(DateTime.UtcNow));

Creazione di un filtro

Prima di leggere i dati che hai scritto, crea un filtro per limitare i dati restituiti da Bigtable. Questo filtro indica a Bigtable di restituire solo la versione più recente di ogni valore, anche se la tabella contiene celle precedenti idonee alla garbage collection, ma non ancora eliminate.

RowFilter filter = RowFilters.CellsPerRowLimit(1);

Lettura di una riga tramite la relativa chiave di riga

Utilizza il metodo ReadRow(), passando il filtro appena creato, per ottenere una versione di ogni valore in quella riga.

// Read from the table.
Console.WriteLine("Read the first row");

int rowIndex = 0;

// Read a specific row. Apply a filter to return latest only cell value accross entire row.
Row rowRead = bigtableClient.ReadRow(
    tableName, rowKey: rowKeyPrefix + rowIndex, filter: filter);
Console.WriteLine(
    $"\tRow key: {rowRead.Key.ToStringUtf8()} " +
    $"  -- Value: {rowRead.Families[0].Columns[0].Cells[0].Value.ToStringUtf8(),-16} " +
    $"  -- Time Stamp: {rowRead.Families[0].Columns[0].Cells[0].TimestampMicros}");

Analisi di tutte le righe della tabella

Richiama il metodo ReadRows(), passando il filtro, per visualizzare tutte le righe della tabella. Poiché hai passato il filtro, Bigtable restituisce solo una versione per ciascun valore.

Console.WriteLine("Read all rows using streaming");
// stream the content of the whole table. Apply a filter to return latest only cell values accross all rows.
ReadRowsStream responseRead = bigtableClient.ReadRows(tableName, filter: filter);

Task printRead = PrintReadRowsAsync();
printRead.Wait();

async Task PrintReadRowsAsync()
{
    var responseEnumerator = responseRead.GetAsyncEnumerator(default);
    while (await responseEnumerator.MoveNextAsync())
    {
        Row row = responseEnumerator.Current;
        Console.WriteLine(
            $"\tRow key: {row.Key.ToStringUtf8()} " +
            $"  -- Value: {row.Families[0].Columns[0].Cells[0].Value.ToStringUtf8(),-16} " +
            $"  -- Time Stamp: {row.Families[0].Columns[0].Cells[0].TimestampMicros}");
    }
}

Eliminazione di una tabella

Elimina la tabella con il metodo DeleteTable().

// Clean up. Delete the table.
Console.WriteLine($"Delete table: {tableId}");

bigtableTableAdminClient.DeleteTable(name: tableName);
if (!TableExist(bigtableTableAdminClient))
{
    Console.WriteLine($"Table: {tableId} deleted successfully");
}

Riepilogo

Ecco l'esempio di codice completo senza commenti.

// Copyright 2018 Google Inc.

using Google.Cloud.Bigtable.Admin.V2;
using Google.Cloud.Bigtable.V2;
using Grpc.Core;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace GoogleCloudSamples.Bigtable
{
    public class HelloWorld
    {
        private const string projectId = "YOUR-PROJECT-ID";

        private const string instanceId = "YOUR-INSTANCE-ID";

        private const string tableId = "Hello-Bigtable";
        private const string columnFamily = "cf";
        private const string columnName = "greeting";
        private static readonly string[] s_greetings = { "Hello World!", "Hello Bigtable!", "Hello C#!" };
        private static List<int> s_mapToOriginalGreetingIndex;
        private const string rowKeyPrefix = "greeting";
        private static int s_greetingIndex;

        private static void DoHelloWorld()
        {
            try
            {
                BigtableTableAdminClient bigtableTableAdminClient = BigtableTableAdminClient.Create();

                BigtableClient bigtableClient = BigtableClient.Create();

                Console.WriteLine($"Create new table: {tableId} with column family: {columnFamily}, instance: {instanceId}");

                if (!TableExist(bigtableTableAdminClient))
                {
                    bigtableTableAdminClient.CreateTable(
                        new InstanceName(projectId, instanceId),
                        tableId,
                        new Table
                        {
                            Granularity = Table.Types.TimestampGranularity.Millis,
                            ColumnFamilies =
                            {
                                {
                                    columnFamily, new ColumnFamily
                                    {
                                        GcRule = new GcRule
                                        {
                                            MaxNumVersions = 1
                                        }
                                    }
                                }
                            }
                        });
                    Console.WriteLine(TableExist(bigtableTableAdminClient)
                        ? $"Table {tableId} created successfully\n"
                        : $"There was a problem creating a table {tableId}");
                }
                else
                {
                    Console.WriteLine($"Table: {tableId} already exists");
                }

                Google.Cloud.Bigtable.Common.V2.TableName tableName = new Google.Cloud.Bigtable.Common.V2.TableName(projectId, instanceId, tableId);

                       Note: This example uses sequential numeric IDs for simplicity, but
                       this can result in poor performance in a production application.
                       Since rows are stored in sorted order by key, sequential keys can
                       result in poor distribution of operations across nodes.

                       For more information about how to design a Bigtable schema for the
                       best performance, see the documentation:

                       https://cloud.google.com/bigtable/docs/schema-design */

                Console.WriteLine($"Write some greetings to the table {tableId}");

                s_greetingIndex = 0;
                try
                {
                    bigtableClient.MutateRow(tableName, rowKeyPrefix + s_greetingIndex, MutationBuilder());
                    Console.WriteLine($"\tGreeting:   -- {s_greetings[s_greetingIndex],-18}-- written successfully");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"\tFailed to write greeting: --{s_greetings[s_greetingIndex]}");
                    Console.WriteLine(ex.Message);
                    throw;
                }

                MutateRowsRequest request = new MutateRowsRequest
                {
                    TableNameAsTableName = tableName
                };

                s_mapToOriginalGreetingIndex = new List<int>();
                while (++s_greetingIndex < s_greetings.Length)
                {
                    s_mapToOriginalGreetingIndex.Add(s_greetingIndex);
                    string rowKey = rowKeyPrefix + s_greetingIndex;
                    request.Entries.Add(Mutations.CreateEntry(rowKey, MutationBuilder()));
                }

                MutateRowsResponse response = bigtableClient.MutateRows(request);

                foreach (MutateRowsResponse.Types.Entry entry in response.Entries)
                {
                    s_greetingIndex = s_mapToOriginalGreetingIndex[(int)entry.Index];
                    if (entry.Status.Code == 0)
                    {
                        Console.WriteLine($"\tGreeting:   -- {s_greetings[s_greetingIndex],-18}-- written successfully");
                    }
                    else
                    {
                        Console.WriteLine($"\tFailed to write greeting: --{s_greetings[s_greetingIndex]}");
                        Console.WriteLine(entry.Status.Message);
                    }
                }

                Mutation MutationBuilder() =>
                    Mutations.SetCell(columnFamily, columnName, s_greetings[s_greetingIndex], new BigtableVersion(DateTime.UtcNow));

                RowFilter filter = RowFilters.CellsPerRowLimit(1);

                Console.WriteLine("Read the first row");

                int rowIndex = 0;

                Row rowRead = bigtableClient.ReadRow(
                    tableName, rowKey: rowKeyPrefix + rowIndex, filter: filter);
                Console.WriteLine(
                    $"\tRow key: {rowRead.Key.ToStringUtf8()} " +
                    $"  -- Value: {rowRead.Families[0].Columns[0].Cells[0].Value.ToStringUtf8(),-16} " +
                    $"  -- Time Stamp: {rowRead.Families[0].Columns[0].Cells[0].TimestampMicros}");

                Console.WriteLine("Read all rows using streaming");
                ReadRowsStream responseRead = bigtableClient.ReadRows(tableName, filter: filter);

                Task printRead = PrintReadRowsAsync();
                printRead.Wait();

                async Task PrintReadRowsAsync()
                {
                    var responseEnumerator = responseRead.GetAsyncEnumerator(default);
                    while (await responseEnumerator.MoveNextAsync())
                    {
                        Row row = responseEnumerator.Current;
                        Console.WriteLine(
                            $"\tRow key: {row.Key.ToStringUtf8()} " +
                            $"  -- Value: {row.Families[0].Columns[0].Cells[0].Value.ToStringUtf8(),-16} " +
                            $"  -- Time Stamp: {row.Families[0].Columns[0].Cells[0].TimestampMicros}");
                    }
                }

                Console.WriteLine($"Delete table: {tableId}");

                bigtableTableAdminClient.DeleteTable(name: tableName);
                if (!TableExist(bigtableTableAdminClient))
                {
                    Console.WriteLine($"Table: {tableId} deleted successfully");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception while running HelloWorld: {ex.Message}");
            }
        }

        private static bool TableExist(BigtableTableAdminClient bigtableTableAdminClient)
        {
            GetTableRequest request = new GetTableRequest
            {
                TableName = new Google.Cloud.Bigtable.Common.V2.TableName(projectId, instanceId, tableId),
                View = Table.Types.View.NameOnly
            };
            try
            {
                var tables = bigtableTableAdminClient.GetTable(request);
                return true;
            }
            catch (RpcException ex)
            {
                if (ex.StatusCode == StatusCode.NotFound)
                {
                    return false;
                }

                throw;
            }
        }

        public static int Main(string[] args)
        {
            if (projectId == "YOUR-PROJECT" + "-ID")
            {
                Console.WriteLine("Edit HelloWorld.cs and replace YOUR-PROJECT-ID with your project ID.");
                return -1;
            }
            if (instanceId == "YOUR-INSTANCE" + "-ID")
            {
                Console.WriteLine("Edit HelloWorld.cs and replace YOUR-INSTANCE-ID with your instance ID.");
                return -1;
            }

            DoHelloWorld();
            return 0;
        }
    }
}