Så här använder du Azure Table Storage och Azure Cosmos DB för table med C++

GÄLLER FÖR: Tabell

Dricks

Innehållet i den här artikeln gäller för Azure Table Storage och Azure Cosmos DB for Table. API för tabell är ett premiumerbjudande för tabelllagring som erbjuder dataflödesoptimerade tabeller, global distribution och automatiska sekundära index.

Den här guiden visar vanliga scenarier med hjälp av Azure Table Storage-tjänsten eller Azure Cosmos DB for Table. Exemplen är skrivna i C++ och använder Azure Storage-klientbiblioteket för C++. I denna artikel beskrivs följande scenarier:

  • Skapa och ta bort en tabell
  • Arbeta med tabellentiteter

Kommentar

För den här guiden krävs Azure Storage-klientbiblioteket för C++ version 1.0.0 eller senare. Den rekommenderade versionen är Storage Client Library 2.2.0, som är tillgängligt med hjälp av NuGet eller GitHub.

Skapa konton

Skapa ett Azure-tjänstkonto

Du kan arbeta med tabeller med hjälp av Azure Table Storage eller Azure Cosmos DB. Mer information om skillnaderna mellan tabellerbjudanden i dessa två tjänster finns i API:et för tabellöversikt. Du måste skapa ett konto för den tjänst som du ska använda. Följande avsnitt visar hur du skapar både Azure Table Storage och Azure Cosmos DB-kontot, men du kan bara använda en av dem.

Skapa ett Azure Storage-konto

Det enklaste sättet att skapa ett Azure-lagringskonto är att använda Azure-portalen. För mer information, se Skapa ett lagringskonto.

Du kan även skapa ett Azure-lagringskonto med hjälp av Azure PowerShell eller Azure CLI.

Om du föredrar att inte skapa ett lagringskonto just nu kan du även använda Azure Storage-emulatorn för att köra och testa koden i en lokal miljö. Mer information finns i Använda Azure Storage-emulatorn för utveckling och testning.

Skapa ett Azure Cosmos DB för tabellkonto

Anvisningar om hur du skapar ett Azure Cosmos DB för tabellkonto finns i Skapa ett databaskonto.

Skapa ett C++-program

I den här guiden använder du lagringsfunktioner från ett C++-program. Det gör du genom att installera Azure Storage-klientbiblioteket för C++.

Om du vill installera Azure Storage-klientbiblioteket för C++använder du följande metoder:

.\vcpkg.exe install azure-storage-cpp

Du hittar en guide för hur du skapar källkoden och exporterar till Nuget i README-filen .

Konfigurera åtkomst till klientbiblioteket för Table Storage

Om du vill använda Azure Storage-API:erna för att komma åt tabeller lägger du till följande include instruktioner överst i C++-filen:

#include <was/storage_account.h>
#include <was/table.h>

En Azure Storage-klient eller Azure Cosmos DB-klient använder en anslutningssträng för att lagra slutpunkter och autentiseringsuppgifter för åtkomst till datahanteringstjänster. När du kör ett klientprogram måste du ange anslutningssträng eller Azure Cosmos DB-anslutningssträng i lämpligt format.

Konfigurera en Azure Storage-anslutningssträng

Det här exemplet visar hur du deklarerar ett statiskt fält som ska innehålla Azure Storage-anslutningssträng:

// Define the Storage connection string with your values.
const utility::string_t storage_connection_string(U("DefaultEndpointsProtocol=https;AccountName=<your_storage_account>;AccountKey=<your_storage_account_key>"));

Använd namnet på lagringskontot för <your_storage_account>. För <your_storage_account_key> använder du åtkomstnyckeln för lagringskontot som anges i Azure-portalen. Information om lagringskonton och åtkomstnycklar finns i Skapa ett lagringskonto.

Konfigurera en Azure Cosmos DB-anslutningssträng

Det här exemplet visar hur du deklarerar ett statiskt fält som ska innehålla Azure Cosmos DB-anslutningssträng:

// Define the Azure Cosmos DB connection string with your values.
const utility::string_t storage_connection_string(U("DefaultEndpointsProtocol=https;AccountName=<your_cosmos_db_account>;AccountKey=<your_cosmos_db_account_key>;TableEndpoint=<your_cosmos_db_endpoint>"));

Använd namnet på ditt Azure Cosmos DB-konto för <your_cosmos_db_account>. Ange primärnyckeln för <your_cosmos_db_account_key>. Ange slutpunkten som anges i Azure-portalen för <your_cosmos_db_endpoint>.

Om du vill testa ditt program på din lokala Windows-baserade dator kan du använda Azure Storage-emulatorn som är installerad med Azure SDK. Lagringsemulatorn är ett verktyg som simulerar de Azure Blob-, Queue- och Table-tjänster som är tillgängliga på din lokala utvecklingsdator. I följande exempel visas hur du deklarerar ett statiskt fält för att lagra anslutningssträng till din lokala lagringsemulator:

// Define the connection string with Azure Storage Emulator.
const utility::string_t storage_connection_string(U("UseDevelopmentStorage=true;"));  

Starta Azure Storage-emulatorn genom att välja startknappen eller Windows-nyckeln från Skrivbordet i Windows. Ange och kör Microsoft Azure Storage-emulatorn. Mer information finns i Använda Azure Storage-emulatorn för utveckling och testning.

Hämta anslutningssträngen

Du kan använda cloud_storage_account klassen för att representera din lagringskontoinformation. Om du vill hämta lagringskontoinformationen från lagrings-anslutningssträng använder du parse metoden .

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

Hämta sedan en referens till en cloud_table_client klass. Med den här klassen kan du hämta referensobjekt för tabeller och entiteter som lagras i Table Storage-tjänsten. Följande kod skapar ett cloud_table_client objekt med hjälp av lagringskontoobjektet som du hämtade tidigare:

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

Skapa och lägga till entiteter i en tabell

Skapa en tabell

Med ett cloud_table_client objekt kan du hämta referensobjekt för tabeller och entiteter. Följande kod skapar ett cloud_table_client objekt och använder det för att skapa en ny tabell.

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);  

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

// Retrieve a reference to a table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));

// Create the table if it doesn't exist.
table.create_if_not_exists();  

Lägga till en entitet i en tabell

Om du vill lägga till en entitet i en tabell skapar du ett nytt table_entity objekt och skickar det till table_operation::insert_entity. I följande kod används kundens förnamn som radnyckel och efternamnet som partitionsnyckel. Tillsammans identifierar en entitets partition och radnyckel entiteten i tabellen unikt. Entiteter med samma partitionsnyckel kan efterfrågas snabbare än entiteter med olika partitionsnycklar. Om du använder olika partitionsnycklar kan du använda mer parallell skalbarhet. Mer information finns i checklistan för prestanda och skalbarhet i Microsoft Azure Storage.

Följande kod skapar en ny instans av table_entity med vissa kunddata att lagra. Koden anropar table_operation::insert_entity sedan för att skapa ett table_operation objekt för att infoga en entitet i en tabell och associerar den nya tabellentiteten med den. Slutligen anropar execute koden -metoden för cloud_table objektet. Den nya table_operation skickar en begäran till tabelltjänsten om att infoga den nya kundentiteten i people tabellen.

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

// Retrieve a reference to a table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));

// Create the table if it doesn't exist.
table.create_if_not_exists();

// Create a new customer entity.
azure::storage::table_entity customer1(U("Harp"), U("Walter"));

azure::storage::table_entity::properties_type& properties = customer1.properties();
properties.reserve(2);
properties[U("Email")] = azure::storage::entity_property(U("Walter@contoso.com"));

properties[U("Phone")] = azure::storage::entity_property(U("425-555-0101"));

// Create the table operation that inserts the customer entity.
azure::storage::table_operation insert_operation = azure::storage::table_operation::insert_entity(customer1);

// Execute the insert operation.
azure::storage::table_result insert_result = table.execute(insert_operation);

Infoga en batch med entiteter

Du kan infoga en batch med entiteter i Table Storage i samma skrivåtgärd. Följande kod skapar ett table_batch_operation objekt och lägger sedan till tre infogningsåtgärder i det. Varje infogningsåtgärd läggs till genom att ett nytt entitetsobjekt skapas, dess värden anges och sedan anropas insert metoden för table_batch_operation objektet för att associera entiteten med en ny infogningsåtgärd. Sedan anropar cloud_table.execute koden för att köra åtgärden.

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));

// Define a batch operation.
azure::storage::table_batch_operation batch_operation;

// Create a customer entity and add it to the table.
azure::storage::table_entity customer1(U("Smith"), U("Jeff"));

azure::storage::table_entity::properties_type& properties1 = customer1.properties();
properties1.reserve(2);
properties1[U("Email")] = azure::storage::entity_property(U("Jeff@contoso.com"));
properties1[U("Phone")] = azure::storage::entity_property(U("425-555-0104"));

// Create another customer entity and add it to the table.
azure::storage::table_entity customer2(U("Smith"), U("Ben"));

azure::storage::table_entity::properties_type& properties2 = customer2.properties();
properties2.reserve(2);
properties2[U("Email")] = azure::storage::entity_property(U("Ben@contoso.com"));
properties2[U("Phone")] = azure::storage::entity_property(U("425-555-0102"));

// Create a third customer entity to add to the table.
azure::storage::table_entity customer3(U("Smith"), U("Denise"));

azure::storage::table_entity::properties_type& properties3 = customer3.properties();
properties3.reserve(2);
properties3[U("Email")] = azure::storage::entity_property(U("Denise@contoso.com"));
properties3[U("Phone")] = azure::storage::entity_property(U("425-555-0103"));

// Add customer entities to the batch insert operation.
batch_operation.insert_or_replace_entity(customer1);
batch_operation.insert_or_replace_entity(customer2);
batch_operation.insert_or_replace_entity(customer3);

// Execute the batch operation.
std::vector<azure::storage::table_result> results = table.execute_batch(batch_operation);

Några saker att tänka på när du använder batchåtgärder:

  • Du kan utföra upp till 100 insert, delete, merge, replace, insert-or-mergeoch insert-or-replace åtgärder i valfri kombination i en enda batch.
  • En batchåtgärd kan ha en hämtningsåtgärd, om det är den enda åtgärden i batchen.
  • Alla entiteter i samma batchåtgärd måste ha samma partitionsnyckel.
  • Batchåtgärder är begränsade till en nyttolast på 4 MB.

Fråga efter och ändra entiteter

Hämta alla entiteter i en partition

Om du vill köra frågor mot en tabell för alla entiteter i en partition använder du ett table_query objekt. I följande kodexempel anges ett filter för entiteter där Smith är partitionsnyckeln. Det här exemplet skriver ut fälten för varje entitet i frågeresultatet till konsolen.

Kommentar

Dessa metoder stöds inte för närvarande för C++ i Azure Cosmos DB.

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));

// Construct the query operation for all customer entities where PartitionKey="Smith".
azure::storage::table_query query;

query.set_filter_string(azure::storage::table_query::generate_filter_condition(U("PartitionKey"), azure::storage::query_comparison_operator::equal, U("Smith")));

// Execute the query.
azure::storage::table_query_iterator it = table.execute_query(query);

// Print the fields for each customer.
azure::storage::table_query_iterator end_of_results;
for (; it != end_of_results; ++it)
{
    const azure::storage::table_entity::properties_type& properties = it->properties();

    std::wcout << U("PartitionKey: ") << it->partition_key() << U(", RowKey: ") << it->row_key()
        << U(", Property1: ") << properties.at(U("Email")).string_value()
        << U(", Property2: ") << properties.at(U("Phone")).string_value() << std::endl;
}  

Frågan i det här exemplet returnerar alla entiteter som matchar filtervillkoren. Om du har stora tabeller och ofta behöver hämta tabellentiteterna rekommenderar vi att du lagrar dina data i Azure Storage-blobbar i stället.

Hämta ett intervall med enheter i en partition

Om du inte vill köra frågor mot alla entiteter i en partition kan du ange ett intervall. Kombinera partitionsnyckelfiltret med ett radnyckelfilter. I följande kodexempel används två filter för att hämta alla entiteter i partitionen Smith där radnyckeln (förnamnet) börjar med en bokstav tidigare än E i alfabetet och skriver sedan ut frågeresultatet.

Kommentar

Dessa metoder stöds inte för närvarande för C++ i Azure Cosmos DB.

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));

// Create the table query.
azure::storage::table_query query;

query.set_filter_string(azure::storage::table_query::combine_filter_conditions(
    azure::storage::table_query::generate_filter_condition(U("PartitionKey"),
    azure::storage::query_comparison_operator::equal, U("Smith")),
    azure::storage::query_logical_operator::op_and,
    azure::storage::table_query::generate_filter_condition(U("RowKey"), azure::storage::query_comparison_operator::less_than, U("E"))));

// Execute the query.
azure::storage::table_query_iterator it = table.execute_query(query);

// Loop through the results, displaying information about the entity.
azure::storage::table_query_iterator end_of_results;
for (; it != end_of_results; ++it)
{
    const azure::storage::table_entity::properties_type& properties = it->properties();

    std::wcout << U("PartitionKey: ") << it->partition_key() << U(", RowKey: ") << it->row_key()
        << U(", Property1: ") << properties.at(U("Email")).string_value()
        << U(", Property2: ") << properties.at(U("Phone")).string_value() << std::endl;
}  

Hämta en enda entitet

Du kan skriva en fråga för att hämta en enda, specifik entitet. Följande kod använder table_operation::retrieve_entity för att ange kunden Jeff Smith. Den här metoden returnerar bara en entitet i stället för en samling, och det returnerade värdet finns i table_result. Det snabbaste sättet att hämta en enskild entitet från tabelltjänsten är att ange både partitions- och radnycklar i en fråga.

azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));

// Retrieve the entity with partition key of "Smith" and row key of "Jeff".
azure::storage::table_operation retrieve_operation = azure::storage::table_operation::retrieve_entity(U("Smith"), U("Jeff"));
azure::storage::table_result retrieve_result = table.execute(retrieve_operation);

// Output the entity.
azure::storage::table_entity entity = retrieve_result.entity();
const azure::storage::table_entity::properties_type& properties = entity.properties();

std::wcout << U("PartitionKey: ") << entity.partition_key() << U(", RowKey: ") << entity.row_key()
    << U(", Property1: ") << properties.at(U("Email")).string_value()
    << U(", Property2: ") << properties.at(U("Phone")).string_value() << std::endl;

Ersätta en entitet

Om du vill ersätta en entitet hämtar du den från Table Storage, ändrar entitetsobjektet och sparar sedan ändringarna till Table Storage igen. Följande kod ändrar en befintlig kunds telefonnummer och e-postadress. I stället för att anropa table_operation::insert_entityanvänder table_operation::replace_entityden här koden . Den här metoden gör att entiteten ersätts helt på servern, såvida inte entiteten på servern har ändrats sedan den hämtades. Om den har ändrats misslyckas åtgärden. Det här felet hindrar ditt program från att skriva över en ändring som gjorts mellan hämtningen och uppdateringen av en annan komponent. Rätt hantering av det här felet är att hämta entiteten igen, göra dina ändringar, om de fortfarande är giltiga och sedan utföra en annan table_operation::replace_entity åtgärd.

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));

// Replace an entity.
azure::storage::table_entity entity_to_replace(U("Smith"), U("Jeff"));
azure::storage::table_entity::properties_type& properties_to_replace = entity_to_replace.properties();
properties_to_replace.reserve(2);

// Specify a new phone number.
properties_to_replace[U("Phone")] = azure::storage::entity_property(U("425-555-0106"));

// Specify a new email address.
properties_to_replace[U("Email")] = azure::storage::entity_property(U("JeffS@contoso.com"));

// Create an operation to replace the entity.
azure::storage::table_operation replace_operation = azure::storage::table_operation::replace_entity(entity_to_replace);

// Submit the operation to the Table service.
azure::storage::table_result replace_result = table.execute(replace_operation);

Infoga eller ersätta en entitet

table_operation::replace_entity åtgärder misslyckas om entiteten har ändrats sedan den hämtades från servern. Dessutom måste du hämta entiteten från servern först för table_operation::replace_entity att lyckas. Ibland vet du inte om entiteten finns på servern. De aktuella värden som lagras i den är irrelevanta eftersom uppdateringen bör skriva över dem alla. Använd en table_operation::insert_or_replace_entity åtgärd för att uppnå det här resultatet. Den här åtgärden infogar entiteten om den inte finns. Åtgärden ersätter entiteten om den finns. I följande kodexempel hämtas kundentiteten för Jeff Smith fortfarande, men den sparas sedan tillbaka till servern med hjälp table_operation::insert_or_replace_entityav . Eventuella entitetsuppdateringar som görs mellan hämtnings- och uppdateringsåtgärden skrivs över.

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));

// Insert or replace an entity.
azure::storage::table_entity entity_to_insert_or_replace(U("Smith"), U("Jeff"));
azure::storage::table_entity::properties_type& properties_to_insert_or_replace = entity_to_insert_or_replace.properties();

properties_to_insert_or_replace.reserve(2);

// Specify a phone number.
properties_to_insert_or_replace[U("Phone")] = azure::storage::entity_property(U("425-555-0107"));

// Specify an email address.
properties_to_insert_or_replace[U("Email")] = azure::storage::entity_property(U("Jeffsm@contoso.com"));

// Create an operation to insert or replace the entity.
azure::storage::table_operation insert_or_replace_operation = azure::storage::table_operation::insert_or_replace_entity(entity_to_insert_or_replace);

// Submit the operation to the Table service.
azure::storage::table_result insert_or_replace_result = table.execute(insert_or_replace_operation);

Fråga en deluppsättning entitetsegenskaper

En fråga till en tabell kan hämta några få egenskaper från en entitet. Frågan i följande kod använder table_query::set_select_columns metoden för att endast returnera e-postadresserna för entiteter i tabellen.

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));

// Define the query, and select only the Email property.
azure::storage::table_query query;
std::vector<utility::string_t> columns;

columns.push_back(U("Email"));
query.set_select_columns(columns);

// Execute the query.
azure::storage::table_query_iterator it = table.execute_query(query);

// Display the results.
azure::storage::table_query_iterator end_of_results;
for (; it != end_of_results; ++it)
{
    std::wcout << U("PartitionKey: ") << it->partition_key() << U(", RowKey: ") << it->row_key();

    const azure::storage::table_entity::properties_type& properties = it->properties();
    for (auto prop_it = properties.begin(); prop_it != properties.end(); ++prop_it)
    {
        std::wcout << ", " << prop_it->first << ": " << prop_it->second.str();
    }

    std::wcout << std::endl;
}

Kommentar

Det är effektivare att köra frågor mot några få egenskaper från en entitet än att hämta alla egenskaper.

Ta bort innehåll

Ta bort en entitet

Du kan ta bort en entitet när du har hämtat den. När du har hämtat en entitet anropar table_operation::delete_entity du med entiteten för att ta bort. Anropa cloud_table.execute sedan metoden. Följande kod hämtar och tar bort en entitet med en partitionsnyckel Smith och en radnyckel på Jeff.

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));

// Create an operation to retrieve the entity with partition key of "Smith" and row key of "Jeff".
azure::storage::table_operation retrieve_operation = azure::storage::table_operation::retrieve_entity(U("Smith"), U("Jeff"));
azure::storage::table_result retrieve_result = table.execute(retrieve_operation);

// Create an operation to delete the entity.
azure::storage::table_operation delete_operation = azure::storage::table_operation::delete_entity(retrieve_result.entity());

// Submit the delete operation to the Table service.
azure::storage::table_result delete_result = table.execute(delete_operation);  

Ta bort en tabell

I det sista kodexemplet tas en tabell bort från ett lagringskonto. En tabell som har tagits bort är inte tillgänglig för att återskapas under en tid efter borttagningen.

// Retrieve the storage account from the connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);

// Create the table client.
azure::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();

// Create a cloud table object for the table.
azure::storage::cloud_table table = table_client.get_table_reference(U("people"));

// Delete the table if it exists
if (table.delete_table_if_exists())
{
    std::cout << "Table deleted!";
}
else
{
    std::cout << "Table didn't exist";
}

Felsökning

Om projektet får byggfel på grund av inkluderingsfilerna storage_account.h och table.h för Visual Studio Community Edition tar du bort växeln /permissive- compiler:

  1. Högerklicka på projektet i Solution Explorer och välj Egenskaper.
  2. Expandera Konfigurationsegenskaper i dialogrutan Egenskapssidor, expandera C/C++ och välj Språk.
  3. Ändra Conformance mode (Konformitetsläge) till Nej.

Nästa steg

Microsoft Azure Storage Explorer är en kostnadsfri, fristående app från Microsoft som gör det möjligt att arbeta visuellt med Azure Storage-data i Windows, macOS och Linux.

Följ de här länkarna om du vill veta mer om Azure Storage och API:et för tabell i Azure Cosmos DB: