This sample demonstrates how to query a table for entities. You will need to have previously created a table in the service in order to query entities from it. To get started, you'll need access to either a Storage or Cosmos DB account.
A TableClient
is needed to perform table-level operations like inserting and deleting entities within the table, so it is ideal for dealing with only a specific table. There are two ways to get a TableClient
:
- Call
GetTableClient
from theTableServiceClient
with the table name.
var tableClient2 = serviceClient.GetTableClient(tableName);
- Create a
TableClient
with a SAS URI, an endpoint andTableSharedKeyCredential
, or a connection string.
var tableClient3 = new TableClient(
new Uri(storageUri),
tableName,
new TableSharedKeyCredential(accountName, storageAccountKey));
If you are not familiar with creating tables, refer to the sample on creating and deleting tables.
To query entities that satisfy a specified filter, call Query
, specify the desired entity return type, and pass in a filter in the form of either an OData formatted string or a LINQ expression.
Here is a query returning a collection of dictionary TableEntity
objects that possess the specified partition key.
Pageable<TableEntity> queryResultsFilter = tableClient.Query<TableEntity>(filter: $"PartitionKey eq '{partitionKey}'");
// Iterate the <see cref="Pageable"> to access all queried entities.
foreach (TableEntity qEntity in queryResultsFilter)
{
Console.WriteLine($"{qEntity.GetString("Product")}: {qEntity.GetDouble("Price")}");
}
Console.WriteLine($"The query returned {queryResultsFilter.Count()} entities.");
Hand formatting OData query filters can be tricky, so there is a helper class called QueryFilter
to help make it easier.
For example, OData filters require that strings be single quoted, and DateTime values be single quoted and prefixed with datetime
.
The QueryFilter
class handles all the type escaping for you.
// The CreateQueryFilter method is also available to assist with properly formatting and escaping OData queries.
var queryResultsFilter2 = tableClient.Query<TableEntity>(filter: TableClient.CreateQueryFilter($"PartitionKey eq {partitionKey}"));
// Iterate the <see cref="Pageable"> to access all queried entities.
foreach (TableEntity qEntity in queryResultsFilter2)
{
Console.WriteLine($"{qEntity.GetString("Product")}: {qEntity.GetDouble("Price")}");
}
Console.WriteLine($"The query returned {queryResultsFilter.Count()} entities.");
Here is a query returning a collection of the strongly-typed OfficeSupplyEntity
objects that cost at least $6.00.
To define the strongly-typed class, refer to the sample on creating classes.
double priceCutOff = 6.00;
Pageable<OfficeSupplyEntity> queryResultsLINQ = tableClient.Query<OfficeSupplyEntity>(ent => ent.Price >= priceCutOff);
To query entities and obtain specific properties, call Query
, specify the desired entity return type, and pass in an IEnumerable
populated with the names of properties you would like to retrieve.
Pageable<TableEntity> queryResultsSelect = tableClient.Query<TableEntity>(select: new List<string>() { "Product", "Price" });
To query entities by page, call Query
, specify the desired entity return type, and pass in the desired maximum number of entities per page.
Pageable<TableEntity> queryResultsMaxPerPage = tableClient.Query<TableEntity>(maxPerPage: 10);
// Iterate the <see cref="Pageable"> by page.
foreach (Page<TableEntity> page in queryResultsMaxPerPage.AsPages())
{
Console.WriteLine("This is a new page!");
foreach (TableEntity qEntity in page.Values)
{
Console.WriteLine($"# of {qEntity.GetString("Product")} inventoried: {qEntity.GetInt32("Quantity")}");
}
}
In more advanced scenarios, it may be necessary to store the continuation token returned from the service so your code controls exactly when the next pages is fetched. Below is a simple example that illustrates how the token can be fetched and applied to paginated results.
string continuationToken = null;
bool moreResultsAvailable = true;
while (moreResultsAvailable)
{
Page<TableEntity> page = tableClient
.Query<TableEntity>()
.AsPages(continuationToken, pageSizeHint: 10)
.FirstOrDefault(); // Note: Since the pageSizeHint only limits the number of results in a single page, we explicitly only enumerate the first page.
if (page == null)
break;
// Get the continuation token from the page.
// Note: This value can be stored so that the next page query can be executed later.
continuationToken = page.ContinuationToken;
IReadOnlyList<TableEntity> pageResults = page.Values;
moreResultsAvailable = continuationToken != null;
// Print out the results for this page.
foreach (TableEntity result in pageResults)
{
Console.WriteLine($"{result.PartitionKey}-{result.RowKey}");
}
}