Hello World C#

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

  • Configura l'autenticazione
  • Connettiti a un'istanza Bigtable
  • Crea una nuova tabella.
  • Scrivere i dati nella tabella.
  • Leggi di nuovo i dati.
  • Elimina la tabella.

Configura l'autenticazione

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

  1. Install the Google Cloud CLI.
  2. To initialize the gcloud CLI, run the following command:

    gcloud init
  3. If you're using a local shell, then create local authentication credentials for your user account:

    gcloud auth application-default login

    You don't need to do this if you're using Cloud Shell.

Per ulteriori informazioni, consulta Set up authentication for a local development environment.

Eseguire il sample

Questo codice comunica con Bigtable utilizzando le librerie API di amministrazione C# e API di dati C# nelle librerie client di Google Cloud per .NET.

Per eseguire questo programma di esempio, segui le istruzioni per gli esempi di Bigtable.NET su GitHub. Completa i passaggi Crea ed esegui e Guida rapida per creare risorse che puoi utilizzare nella tua applicazione Hello World. Assicurati di modificare il HelloWorld.cs file 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 mostra alcune operazioni semplici.

Connessione a Bigtable

Per iniziare, crea due oggetti client che puoi utilizzare per connetterti a Bigtable. Le API di amministrazione C# BigtableTableAdminClient ti consentono di creare ed eliminare istanze e tabelle. Le API Data per C# BigtableClient ti 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 memorizza i saluti "ciao mondo". 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 fonte di dati da scrivere nella tabella. Innanzitutto, scrivi una singola riga nella tabella utilizzando MutateRow(). Quindi, esegui un ciclo per il resto dell'array per creare un oggetto MutateRowsRequest che contenga una voce per ogni saluto. Effettua la richiesta di scrittura di tutte le voci contemporaneamente con MutateRows(). Quindi, esamina la risposta restituita per controllare il codice di stato di ogni voce e 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 che Bigtable restituisce. Questo filtro indica a Bigtable di restituire solo la versione più recente di ogni valore, anche se la tabella contiene celle precedenti idonee per il garbage collection, ma che non sono state ancora eliminate.

RowFilter filter = RowFilters.CellsPerRowLimit(1);

Lettura di una riga in base alla 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}");

Scansione di tutte le righe della tabella

Chiama il metodo ReadRows(), passando il filtro, per ottenere tutte le righe della tabella. Poiché hai passato il filtro, Bigtable restituisce una sola versione di 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");
}

In sintesi

Ecco il esempio di codice completo senza commenti.



using Google.Cloud.Bigtable.Admin.V2;
using Google.Cloud.Bigtable.Common.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;
        }
    }
}