Приступая к работе с хранилищем таблиц Azure с помощью .NET

Совет

Сведения в этой статье касаются исходного базового хранилища таблиц Azure. Однако теперь есть расширенная версия хранилища таблиц Azure в виде общедоступной предварительной версии, которая предлагает оптимизированные для пропускной способности таблицы, глобальное распределение и автоматическое вторичное индексирование. Чтобы испытать новые возможности и получить дополнительные сведения, ознакомьтесь со статьей Знакомство со службой Azure Cosmos DB. API таблицы.

Хранилище таблиц Azure — это служба, которая хранит структурированные данные NoSQL в облаке, предоставляя хранилище ключей и атрибутов с бессхемной конструкцией. Такая конструкция хранилища таблиц позволяет легко адаптировать данные по мере расширения приложения. Разным типам приложений может быть предоставлен быстрый и экономичный доступ к хранилищу таблиц. Такое хранилище обычно дешевле, чем традиционные хранилища SQL для похожих объемов данных.

Хранилище таблиц можно использовать для хранения гибких наборов данных, например пользовательских данных для веб-приложений, адресных книг, сведений об устройстве или метаданных любого другого типа, которые требуются вашей службе. В таблице можно хранить любое количество сущностей, а учетная запись хранения может содержать любое количество таблиц в пределах емкости учетной записи.

О данном учебнике

В этом руководстве объясняется, как использовать клиентскую библиотеку хранилища Azure для .NET в распространенных сценариях хранилища таблиц Azure. Эти сценарии представлены с помощью примеров C# для создания и удаления таблиц, а также вставки, обновления, удаления и запроса данных таблицы.

Предварительные требования

Для работы с этим руководством требуются следующие компоненты.

Примечание

Для работы с этим руководством мы рекомендуем использовать последнюю версию клиентской библиотеки службы хранилища Azure для .NET. Последняя версия для скачивания доступна на портале NuGet. Источник клиентской библиотеки см. на портале GitHub.

Если вы используете эмулятор хранения, см. требования к версии клиентской библиотеки в файле README. Использовать клиентскую библиотеку хранилища для .NET необходимо с соответствующей минимальной версией эмулятора хранения Azure.

Другие примеры

Дополнительные примеры использования хранилища таблиц см. в статье Getting Started with Azure Table Storage in .NET (Приступая к работе с хранилищем таблиц Azure в .NET). Вы можете скачать пример приложения и запустить его или просмотреть код на GitHub.

Что такое служба таблиц

В службе хранилища таблиц Azure хранятся большие объемы структурированных данных. Эта служба — хранилище данных NoSQL, которое принимает вызовы внутри и снаружи облака Azure с проверкой подлинности. Таблицы Azure идеально подходят для хранения нереляционных структурированных данных. Наиболее частые способы использования службы таблицы включают следующие.

  • Хранение терабайтов структурированных данных с возможностью обслуживания приложений с веб-масштабированием.
  • Хранение наборов данных, которые не требуют сложных соединений, внешних ключей или хранимых процедур и могут быть денормализованы для обеспечения быстрого доступа.
  • Быстрый запрос данных с помощью кластерного индекса.
  • Доступ к данным с помощью протокола OData и запросов LINQ с библиотеками .NET службы данных WCF.

Службу таблиц можно использовать для хранения и запросов огромных наборов структурированных нереляционных данных, и таблица будет масштабироваться при запросе на увеличение.

Основные понятия службы таблиц

Служба таблиц содержит следующие компоненты:

Схема компонентов службы таблиц

  • Формат URL-адреса. Код обращается к таблицам в учетной записи, используя следующий формат адреса:
    http://<storage account>.table.core.windows.net/<table>

    К таблицам Azure можно обратиться напрямую, используя этот адрес с протоколом OData. Дополнительные сведения можно найти на веб-сайте OData.org.

  • Учетная запись хранения. Весь доступ к хранилищу Azure осуществляется с помощью учетной записи хранения. Сведения об емкости учетной записи хранения см. в статье Целевые показатели масштабируемости и производительности службы хранилища Azure.
  • Таблица. Таблица — это коллекция сущностей. Таблицы не налагают схему на сущности. Это означает, что одна таблица может содержать сущности, которые имеют различные наборы свойств. Количество таблиц, которые может содержать учетная запись хранения, ограничены только емкостью учетной записи хранения.
  • Сущность.Сущность — это набор свойств подобно строке базы данных. Сущность может быть размером до 1 МБ.
  • Свойства.Свойство представляет собой пару "имя-значение". Каждая сущность может содержать до 252 свойств для хранения данных. Каждая сущность имеет также 3 системных свойства, которые определяют ключ раздела, ключ строки и отметку времени. Сущности с тем же ключом раздела можно запросить быстрее, и они добавляются или обновляются с помощью атомарных операций. Ключ строки сущности — это ее уникальный код внутри раздела.

Дополнительные сведения об именовании таблиц и ее свойствах см. в обзорной статье о модели данных службы таблиц.

Создание учетной записи хранения Azure

Самый простой способ создать первую учетную запись хранения Azure — воспользоваться порталом Azure. Дополнительную информацию см. в статье Об учетных записях хранения Azure.

Кроме того, создать учетную запись хранения Azure можно с помощью Azure PowerShell, Azure CLI или клиентской библиотеки поставщика ресурсов хранилища для .NET.

Если вы не хотите сейчас создавать учетную запись хранения, код можно протестировать в локальной среде с помощью эмулятора хранения Azure. Дополнительные сведения см. в статье Использование эмулятора хранения Azure для разработки и тестирования.

Настройка среды разработки

Теперь настройте среду разработки в Visual Studio для работы с примерами кода из этого руководства.

Создание нового проекта консольного приложения Windows

В Visual Studio создайте новое консольное приложение Windows. Ниже показано, как создать консольное приложение в Visual Studio 2017. Эти инструкции применимы и в других версиях Visual Studio.

  1. Выберите Файл > Создать > Проект.
  2. Выберите Установлено > Шаблоны > Visual C# > Классический рабочий стол Windows.
  3. Выберите Консольное приложение (.NET Framework).
  4. Введите имя приложения в поле Имя.
  5. Нажмите кнопку ОК.

Диалоговое окно создания проекта в Visual Studio

Все примеры кода из этого руководства можно добавить в метод Main() в файле Program.cs консольного приложения.

Вы можете использовать клиентскую библиотеку службы хранилища Azure в любом приложении .NET, в том числе в облачной службе Azure, веб-приложении Azure, классическом или мобильном приложении. Для упрощения в этом руководстве мы будем использовать консольное приложение.

Установка необходимых пакетов с помощью NuGet

Для работы с этим руководством вам нужно указать в проекте два пакета:

Вы можете использовать NuGet для установки обоих пакетов. Выполните следующие действия.

  1. Щелкните правой кнопкой мыши проект в обозревателе решений и выберите Управление пакетами NuGet.
  2. Выполните в Интернете поиск по запросу "WindowsAzure.Storage" и нажмите кнопку Установить , чтобы установить клиентскую библиотеку службы хранилища и зависимые компоненты.
  3. Выполните поиск в Интернете по запросу WindowsAzure.ConfigurationManager и нажмите кнопку Установить, чтобы установить Azure Configuration Manager.
Примечание

Клиентская библиотека службы хранилища также доступна в пакете Azure SDK для .NET. Но мы рекомендуем также установить клиентскую библиотеку службы хранилища из NuGet, чтобы всегда иметь ее последнюю версию.

Зависимости ODataLib в клиентской библиотеке хранения для .NET разрешаются с помощью пакетов ODataLib, доступных в NuGet, а не в службах данных WCF. Библиотеки ODataLib можно загрузить напрямую или указать на них ссылку в проекте через NuGet. К специальным пакетам ODataLib, используемым клиентскими библиотеками хранения, относятся OData, Edm и Spatial. Хотя эти библиотеки используются классами хранилища таблиц Azure, они являются обязательными зависимостями для программирования с использованием клиентской библиотеки хранения.

Определение целевой среды

Примеры из этого руководства можно выполнять в двух средах.

  • Вы можете выполнить код в учетной записи хранения Azure в облаке.
  • Вы можете выполнить код в эмуляторе хранения Azure. Эмулятор хранения — это локальная среда, эмулирующая учетную запись хранения Azure в облаке. Эмулятор можно использовать как бесплатный вариант для тестирования и отладки кода, пока приложение находится на стадии разработки. Эмулятор использует известную учетную запись и ключ. Дополнительные сведения см. в статье Использование эмулятора хранения Azure для разработки и тестирования.

Выбрав учетную запись хранения в облаке, скопируйте первичный ключ доступа к этой учетной записи хранения с портала Azure. Дополнительные сведения см. в разделе Просмотр и копирование ключей доступа к хранилищу.

Примечание

Вы можете указать эмулятор хранения, чтобы избежать затрат, связанных с хранилищем Azure. Однако если вы выберете учетную запись хранения Azure в облаке, затраты на выполнение заданий в учебнике будут незначительны.

Настройка строки подключения хранилища

Библиотека клиента хранилища Azure для .NET поддерживает использование строки подключения для настройки конечных точек и учетных данных для доступа к службам хранилища. Строку подключения хранилища рекомендуется хранить в файле конфигурации.

Дополнительные сведения о строках подключения см. в статье Настройка строк подключения службы хранилища Azure.

Примечание

Ключ учетной записи хранения похож на корневой пароль для вашей учетной записи хранения. Не забудьте защитить ключ учетной записи хранения. Не сообщайте его другим пользователям, не определяйте его в коде и не храните его в текстовом файле, доступном другим пользователям. Повторно создайте ключ с помощью портала Azure, если вы считаете, что он мог быть скомпрометирован.

Чтобы настроить строку подключения, откройте файл app.config в обозревателе решений Visual Studio. Добавьте содержимое элемента <appSettings> , показанное ниже. Замените account-name именем своей учетной записи хранения, а account-key — ключом доступа своей учетной записи:

<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
    <appSettings>
        <add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key" />
    </appSettings>
</configuration>

Например, параметр конфигурации может быть приблизительно таким:

<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=storagesample;AccountKey=GMuzNHjlB3S9itqZJHHCnRkrokLkcSyW7yK9BRbGp0ENePunLPwBgpxV1Z/pVo9zpem/2xSHXkMqTHHLcx8XRA==" />

Чтобы указать эмулятор хранения, можно использовать ярлык, который сопоставляется с хорошо известным именем и ключом. В этом случае параметр строки подключения будет таким:

<add key="StorageConnectionString" value="UseDevelopmentStorage=true;" />

Добавление директив using

Добавьте в верхнюю часть файла Program.cs следующие директивы using:

using Microsoft.Azure; // Namespace for CloudConfigurationManager
using Microsoft.WindowsAzure.Storage; // Namespace for CloudStorageAccount
using Microsoft.WindowsAzure.Storage.Table; // Namespace for Table storage types

Анализ строки подключения

Библиотека Microsoft Azure Configuration Manager для .NET содержит класс для анализа строки подключения из файла конфигурации. Класс CloudConfigurationManager анализирует параметры конфигурации независимо от того, где работает клиентское приложение — на настольном компьютере, мобильном устройстве, виртуальной машине Azure или в облачной службе Azure.

Для ссылки на пакет CloudConfigurationManager добавьте следующую директиву using:

using Microsoft.Azure; //Namespace for CloudConfigurationManager

Ниже приведен пример, в котором показано получение строки подключения из файла конфигурации.

// Parse the connection string and return a reference to the storage account.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

Использование диспетчера конфигураций Azure не является обязательным. Вы также можете использовать API, например класс ConfigurationManager для .NET Framework.

Создание клиента службы таблиц

Класс CloudTableClient позволяет получать таблицы и сущности, хранящиеся в хранилище таблиц. Вот один из способов создать клиент службы таблиц.

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

Теперь вы можете написать код, который считывает и записывает данные в хранилище таблиц.

Создание таблицы

В этом примере показано, как создать таблицу, если она не существует:

// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Retrieve a reference to the table.
CloudTable table = tableClient.GetTableReference("people");

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

Добавление сущности в таблицу

Сущности сопоставляются с объектами C# с помощью настраиваемого класса, производного от TableEntity. Чтобы добавить сущность в таблицу, создайте класс, который определяет свойства сущности. Следующий код определяет класс сущностей, который использует имя клиента как ключ строки, а фамилию клиента — как ключ раздела. Вместе ключ раздела и ключ строки сущности уникальным образом идентифицируют сущность в таблице. Сущности с одинаковым ключом раздела можно запрашивать быстрее, чем с разными ключами раздела, но использование различных ключей разделов обеспечивает более высокую масштабируемость параллельных операций. Чтобы сущности могли храниться в таблицах, они должны быть поддерживаемого типа, например производными от класса TableEntity. Свойства сущности, которые вы хотите хранить в таблице, должны быть открытыми свойствами типа и поддерживать получение и настройку значений. Кроме того, тип сущности должен предоставлять конструктор без параметров.

public class CustomerEntity : TableEntity
{
    public CustomerEntity(string lastName, string firstName)
    {
        this.PartitionKey = lastName;
        this.RowKey = firstName;
    }

    public CustomerEntity() { }

    public string Email { get; set; }

    public string PhoneNumber { get; set; }
}

Табличные операции, включающие сущности, выполняются с использованием объекта CloudTable, созданного ранее в разделе "Создание таблицы". Выполняемая операция представляется объектом TableOperation. В следующем примере кода показано создание объекта CloudTable и объекта CustomerEntity. Чтобы подготовить операцию, создается объект TableOperation для вставки сущности customer в таблицу. Наконец, операция выполняется при вызове CloudTable.Execute.

// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Create the CloudTable object that represents the "people" table.
CloudTable table = tableClient.GetTableReference("people");

// Create a new customer entity.
CustomerEntity customer1 = new CustomerEntity("Harp", "Walter");
customer1.Email = "Walter@contoso.com";
customer1.PhoneNumber = "425-555-0101";

// Create the TableOperation object that inserts the customer entity.
TableOperation insertOperation = TableOperation.Insert(customer1);

// Execute the insert operation.
table.Execute(insertOperation);

Вставка пакета сущностей

Вы можете вставить пакет сущностей в таблицу в одной операции записи. Некоторые другие примечания к пакетным операциям:

  • Можно выполнять операции обновления, удаления и вставки в одной операции пакета.
  • Одна пакетная операция может включать до 100 сущностей.
  • У всех сущностей в одной пакетной операции должен быть одинаковый ключ раздела.
  • Хотя запрос можно выполнить как пакетную операцию, он должен быть единственной операцией в пакете.

В следующем примере кода создается два объекта сущности, которые добавляются в TableBatchOperation с помощью метода Insert. Затем вызывается метод CloudTable.ExecuteBatch для выполнения операции.

// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Create the CloudTable object that represents the "people" table.
CloudTable table = tableClient.GetTableReference("people");

// Create the batch operation.
TableBatchOperation batchOperation = new TableBatchOperation();

// Create a customer entity and add it to the table.
CustomerEntity customer1 = new CustomerEntity("Smith", "Jeff");
customer1.Email = "Jeff@contoso.com";
customer1.PhoneNumber = "425-555-0104";

// Create another customer entity and add it to the table.
CustomerEntity customer2 = new CustomerEntity("Smith", "Ben");
customer2.Email = "Ben@contoso.com";
customer2.PhoneNumber = "425-555-0102";

// Add both customer entities to the batch insert operation.
batchOperation.Insert(customer1);
batchOperation.Insert(customer2);

// Execute the batch operation.
table.ExecuteBatch(batchOperation);

Получение всех сущностей в разделе

Чтобы запросить таблицу для всех сущностей в разделе, используйте объект TableQuery. Следующий пример кода задает фильтр для сущностей с ключом раздела Smith. Этот пример выводит на консоль поля каждой сущности в результатах запроса.

// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Create the CloudTable object that represents the "people" table.
CloudTable table = tableClient.GetTableReference("people");

// Construct the query operation for all customer entities where PartitionKey="Smith".
TableQuery<CustomerEntity> query = new TableQuery<CustomerEntity>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "Smith"));

// Print the fields for each customer.
foreach (CustomerEntity entity in table.ExecuteQuery(query))
{
    Console.WriteLine("{0}, {1}\t{2}\t{3}", entity.PartitionKey, entity.RowKey,
        entity.Email, entity.PhoneNumber);
}

Получение диапазона сущностей в разделе

Если вы не хотите запрашивать все сущности в разделе, можно указать диапазон, объединив фильтр ключа раздела с фильтром ключа строк. В следующем примере кода используются два фильтра для получения всех сущностей в разделе Smith, где ключ строки (имя) начинается с буквы алфавита до "E", после чего результаты запроса выводятся в консоль.

// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Create the CloudTable object that represents the "people" table.
CloudTable table = tableClient.GetTableReference("people");

// Create the table query.
TableQuery<CustomerEntity> rangeQuery = new TableQuery<CustomerEntity>().Where(
    TableQuery.CombineFilters(
        TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "Smith"),
        TableOperators.And,
        TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThan, "E")));

// Loop through the results, displaying information about the entity.
foreach (CustomerEntity entity in table.ExecuteQuery(rangeQuery))
{
    Console.WriteLine("{0}, {1}\t{2}\t{3}", entity.PartitionKey, entity.RowKey,
        entity.Email, entity.PhoneNumber);
}

Извлечение одной сущности

Можно написать запрос для получения отдельной сущности. В следующем примере кода с помощью объекта TableOperation задается клиент Ben Smith. Этот метод возвращает только одну сущность, а не коллекцию, а возвращаемое значение в TableResult.Result является объектом CustomerEntity. Указание ключа раздела и ключа строки в запросе — самый быстрый способ извлечь одну сущность из службы таблиц.

// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Create the CloudTable object that represents the "people" table.
CloudTable table = tableClient.GetTableReference("people");

// Create a retrieve operation that takes a customer entity.
TableOperation retrieveOperation = TableOperation.Retrieve<CustomerEntity>("Smith", "Ben");

// Execute the retrieve operation.
TableResult retrievedResult = table.Execute(retrieveOperation);

// Print the phone number of the result.
if (retrievedResult.Result != null)
{
    Console.WriteLine(((CustomerEntity)retrievedResult.Result).PhoneNumber);
}
else
{
    Console.WriteLine("The phone number could not be retrieved.");
}

Замена сущности

Чтобы обновить сущность, извлеките ее из службы таблиц, измените объект сущности и сохраните изменения в службе таблиц. Следующий код изменяет существующий номер телефона клиента. Вместо вызова метода Insert этот код использует операцию Replace. Операция Replace полностью заменяет сущность на сервере, если только сущность на сервере не была изменена с момента извлечения. В таком случае операция не будет выполнена. Это необходимо, чтобы приложение случайно не перезаписало изменения, внесенные с момента извлечения до обновления другим компонентом приложения. Правильный алгоритм обработки этой ошибки заключается в том, чтобы снова получить сущность, внести необходимые изменения (если это еще возможно), а затем выполнить еще одну операцию Replace. Ниже показано, как изменить это поведение.

// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Create the CloudTable object that represents the "people" table.
CloudTable table = tableClient.GetTableReference("people");

// Create a retrieve operation that takes a customer entity.
TableOperation retrieveOperation = TableOperation.Retrieve<CustomerEntity>("Smith", "Ben");

// Execute the operation.
TableResult retrievedResult = table.Execute(retrieveOperation);

// Assign the result to a CustomerEntity object.
CustomerEntity updateEntity = (CustomerEntity)retrievedResult.Result;

if (updateEntity != null)
{
    // Change the phone number.
    updateEntity.PhoneNumber = "425-555-0105";

    // Create the Replace TableOperation.
    TableOperation updateOperation = TableOperation.Replace(updateEntity);

    // Execute the operation.
    table.Execute(updateOperation);

    Console.WriteLine("Entity updated.");
}
else
{
    Console.WriteLine("Entity could not be retrieved.");
}

Вставка или замена сущности

Операции Replace завершаются ошибкой, если сущность изменена с момента получения с сервера. Более того, для успешного выполнения операции Replace сначала нужно получить сущность с сервера. Тем не менее иногда вы не знаете, существует ли сущность на сервере и являются ли текущие значения, хранящиеся на нем, актуальными. Обновление должно заменить их все. Для выполнения этой задачи необходимо использовать операцию InsertOrReplace. Эта операция вставляет сущность, если она не существует, или заменяет ее, если она существует, независимо от того, когда было выполнено последнее обновление.

В следующем примере кода сущность клиента для Fred Jones создается и вставляется в таблицу people. Далее мы используем операцию InsertOrReplace для сохранения сущности с одинаковым ключом раздела (Jones) и ключом строки (Fred) на сервере. На этот раз мы используем ее с другим значением свойства PhoneNumber. Так как мы используем операцию InsertOrReplace, все значения свойства заменяются. Но если сущности Fred Jones еще нет в таблице, ее нужно вставить.

// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Create the CloudTable object that represents the "people" table.
CloudTable table = tableClient.GetTableReference("people");

// Create a customer entity.
CustomerEntity customer3 = new CustomerEntity("Jones", "Fred");
customer3.Email = "Fred@contoso.com";
customer3.PhoneNumber = "425-555-0106";

// Create the TableOperation object that inserts the customer entity.
TableOperation insertOperation = TableOperation.Insert(customer3);

// Execute the operation.
table.Execute(insertOperation);

// Create another customer entity with the same partition key and row key.
// We've already created a 'Fred Jones' entity and saved it to the
// 'people' table, but here we're specifying a different value for the
// PhoneNumber property.
CustomerEntity customer4 = new CustomerEntity("Jones", "Fred");
customer4.Email = "Fred@contoso.com";
customer4.PhoneNumber = "425-555-0107";

// Create the InsertOrReplace TableOperation.
TableOperation insertOrReplaceOperation = TableOperation.InsertOrReplace(customer4);

// Execute the operation. Because a 'Fred Jones' entity already exists in the
// 'people' table, its property values will be overwritten by those in this
// CustomerEntity. If 'Fred Jones' didn't already exist, the entity would be
// added to the table.
table.Execute(insertOrReplaceOperation);

Запрос подмножества свойств сущности

Запрос к таблице может получить лишь несколько свойств сущности, а не все свойства. Этот метод, который называется "проекцией", снижает потребление пропускной способности и может повысить производительность запросов, особенно для крупных сущностей. Запрос в следующем коде возвращает только электронные адреса сущностей в таблице. Это делается с помощью запроса DynamicTableEntity, а также EntityResolver. Дополнительные сведения о проекции см. в записи блога Windows Azure Tables: Introducing Upsert and Query Projection (Таблицы Microsoft Azure: введение в Upsert и проекции в запросах). Проекция не поддерживается в эмуляторе хранения, поэтому этот код выполняется только при использовании учетной записи хранения в службе таблиц.

// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Create the CloudTable that represents the "people" table.
CloudTable table = tableClient.GetTableReference("people");

// Define the query, and select only the Email property.
TableQuery<DynamicTableEntity> projectionQuery = new TableQuery<DynamicTableEntity>().Select(new string[] { "Email" });

// Define an entity resolver to work with the entity after retrieval.
EntityResolver<string> resolver = (pk, rk, ts, props, etag) => props.ContainsKey("Email") ? props["Email"].StringValue : null;

foreach (string projectedEmail in table.ExecuteQuery(projectionQuery, resolver, null, null))
{
    Console.WriteLine(projectedEmail);
}

Удаление сущности

Сущность можно легко удалить после ее получения с использованием того же шаблона, что и для обновления сущностей. Следующий код извлекает и удаляет сущность клиента.

// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Create the CloudTable that represents the "people" table.
CloudTable table = tableClient.GetTableReference("people");

// Create a retrieve operation that expects a customer entity.
TableOperation retrieveOperation = TableOperation.Retrieve<CustomerEntity>("Smith", "Ben");

// Execute the operation.
TableResult retrievedResult = table.Execute(retrieveOperation);

// Assign the result to a CustomerEntity.
CustomerEntity deleteEntity = (CustomerEntity)retrievedResult.Result;

// Create the Delete TableOperation.
if (deleteEntity != null)
{
    TableOperation deleteOperation = TableOperation.Delete(deleteEntity);

    // Execute the operation.
    table.Execute(deleteOperation);

    Console.WriteLine("Entity deleted.");
}
else
{
    Console.WriteLine("Could not retrieve the entity.");
}

Удаление таблицы

Наконец, следующий пример кода удаляет таблицу из учетной записи хранения. Удаленную таблицу нельзя воссоздать в течение определенного времени после удаления.

// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString"));

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Create the CloudTable that represents the "people" table.
CloudTable table = tableClient.GetTableReference("people");

// Delete the table it if exists.
table.DeleteIfExists();

Асинхронное получение объектов со страниц

Если необходимо считать большое количество объектов, обрабатывая или отображая их по мере получения (до завершения всей операции), для их получения можно использовать сегментированный запрос. В этом примере объясняется, как расположить запрошенные результаты на странице с помощью алгоритма Async-Await для того, чтобы не блокировать выполнение задачи ожиданием большого объема возвращаемых данных. Дополнительные сведения об использовании алгоритма Async-Await в .NET см. в статье Асинхронное программирование с использованием ключевых слов Async и Await (C# и Visual Basic).

// Initialize a default TableQuery to retrieve all the entities in the table.
TableQuery<CustomerEntity> tableQuery = new TableQuery<CustomerEntity>();

// Initialize the continuation token to null to start from the beginning of the table.
TableContinuationToken continuationToken = null;

do
{
    // Retrieve a segment (up to 1,000 entities).
    TableQuerySegment<CustomerEntity> tableQueryResult =
        await table.ExecuteQuerySegmentedAsync(tableQuery, continuationToken);

    // Assign the new continuation token to tell the service where to
    // continue on the next iteration (or null if it has reached the end).
    continuationToken = tableQueryResult.ContinuationToken;

    // Print the number of rows retrieved.
    Console.WriteLine("Rows retrieved {0}", tableQueryResult.Results.Count);

// Loop until a null continuation token is received, indicating the end of the table.
} while(continuationToken != null);

Дальнейшие действия

Вы изучили основные сведения о табличном хранилище. Дополнительные сведения о более сложных задачах по использованию хранилища можно найти по следующим ссылкам.