Rychlý start: Vytvoření rozhraní API pro tabulky pomocí sady .NET SDK a Azure Cosmos DB
PLATÍ pro:
rozhraní API pro tabulky
Tento rychlý start ukazuje, jak získat přístup ke službě Azure Cosmos DB rozhraní API pro tabulky z aplikace .NET. Služba Cosmos DB rozhraní API pro tabulky je úložiště dat bez schématu, které aplikacím umožňuje ukládat strukturovaná data NoSQL v cloudu. Vzhledem k tomu, že se data ukládají v návrhu bez schématu, při přidání objektu s novým atributem do tabulky se do tabulky automaticky přidávají nové vlastnosti (sloupce).
Aplikace .NET mají přístup k Cosmos DB rozhraní API pro tabulky pomocí balíčku Azure.Data.Tables NuGet. Balíček Azure.Data.Tables je knihovna .NET Standard 2.0, která funguje s aplikacemi .NET Framework (4.7.2 a novější) a .NET Core (2.0 a novější).
Požadavky
Ukázková aplikace je napsaná v .NET Core 3.1,i když tyto principy platí pro aplikace .NET Framework i .NET Core. Jako integrované vývojové Visual Studio můžete Visual Studio pro Mac, nebo Visual Studio Code.
Pokud ještě nemáte předplatné Azure, vytvořte si bezplatný účet před tím, než začnete.
Ukázková aplikace
Ukázkovou aplikaci pro tento kurz je možné naklonovat nebo stáhnout z úložiště https://github.com/Azure-Samples/msdocs-azure-data-tables-sdk-dotnet . Úvodní i dokončená aplikace jsou součástí ukázkového úložiště.
git clone https://github.com/Azure-Samples/msdocs-azure-data-tables-sdk-dotnet
Ukázková aplikace používá data o počasí jako příklad k předvedení schopností rozhraní API pro tabulky. Objekty, které představují pozorování počasí, se ukládají a načítá pomocí rozhraní API pro tabulky, včetně ukládání objektů s dalšími vlastnostmi, které demonstrují možnosti bez schématu rozhraní API pro tabulky.
1. Vytvoření účtu Azure Cosmos DB
Nejprve musíte vytvořit účet Cosmos DB Tables API, který bude obsahovat tabulky použité ve vaší aplikaci. Můžete k tomu použít Azure Portal, Azure CLI nebo Azure PowerShell.
Přihlaste se k Azure Portal a podle těchto kroků vytvořte účet Cosmos DB.
2. Vytvoření tabulky
Dále je potřeba vytvořit tabulku v rámci účtu Cosmos DB, kterou bude vaše aplikace používat. Na rozdíl od tradiční databáze potřebujete pouze zadat název tabulky, nikoli vlastnosti (sloupce) v tabulce. Při načítání dat do tabulky se podle potřeby automaticky vytvoří vlastnosti (sloupce).
V části Azure Portalprovedením následujících kroků vytvořte tabulku uvnitř účtu Cosmos DB.
3. Získání připojovacího Cosmos DB
Pro přístup k tabulkám v Cosmos DB bude vaše aplikace potřebovat připojovací řetězec tabulky pro účet Storage CosmosDB. Připojovací řetězec je možné načíst pomocí Azure Portal, Azure CLI nebo Azure PowerShell.
Připojovací řetězec pro váš účet Cosmos DB se považuje za tajný kód aplikace a musí být chráněn jako jakýkoli jiný tajný kód nebo heslo aplikace. Tento příklad používá nástroj Secret Manager k uložení připojovacího řetězce během vývoje a jeho z dispozici pro aplikaci. Nástroj Secret Manager je přístupný z rozhraní příkazového Visual Studio rozhraní příkazového řádku .NET CLI.
Pokud chcete nástroj Secret Manager otevřít v Visual Studio, klikněte pravým tlačítkem na projekt a v místní nabídce vyberte Manage User Secrets (Spravovat tajné kódy uživatelů). Tím se otevře soubor secrets.json pro projekt. Nahraďte obsah souboru následujícím kódem JSON a nahraďte připojovacím řetězcem tabulky Cosmos DB.
{
"ConnectionStrings": {
"CosmosTableApi": "<cosmos db table connection string>"
}
}
4. Instalace NuGet Azure.Data.Tables
Pokud chcete získat Cosmos DB rozhraní API pro tabulky z aplikace .NET, nainstalujte balíček Azure.Data.Tables NuGet.
Install-Package Azure.Data.Tables
5. Konfigurace klienta tabulky v souboru Startup.cs
Sada Azure SDK komunikuje s Azure pomocí klientských objektů k provádění různých operací v Azure. Objekt TableClient je objekt používaný ke komunikaci s Cosmos DB rozhraní API pro tabulky.
Aplikace obvykle vytvoří jeden objekt TableClient pro každou tabulku, který se bude používat v celé aplikaci. K tomu se doporučuje použít injektáž závislostí (DI) a zaregistrovat objekt TableClient jako jednu položku. Další informace o používání injektáže závislostí se sadou Azure SDK najdete v tématu Injektáž závislostí pomocí sady Azure SDK pro .NET.
V Startup.cs souboru aplikace upravte metodu ConfigureServices() tak, aby odpovídala následujícímu fragmentu kódu:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages()
.AddMvcOptions(options =>
{
options.Filters.Add(new ValidationFilter());
});
var connectionString = Configuration.GetConnectionString("CosmosTableApi");
services.AddSingleton<TableClient>(new TableClient(connectionString, "WeatherData"));
services.AddSingleton<TablesService>();
}
Na začátek souboru Startup.cs budete také muset přidat následující příkaz using.
using Azure.Data.Tables;
6. Implementace operací Cosmos DB
Všechny Cosmos db pro ukázkovou aplikaci jsou implementovány ve třídě TableService umístěné v adresáři Služby. Abyste v balíčku SDK pracovali s objekty, budete muset na začátek tohoto souboru importovat obory Azure Azure.Data.Tables názvů a Azure.Data.Tables .
using Azure;
using Azure.Data.Tables;
Na začátek třídy přidejte členská proměnná pro objekt TableClient a konstruktor, který umožní vloženého objektu TableService TableClient do třídy .
private TableClient _tableClient;
public TablesService(TableClient tableClient)
{
_tableClient = tableClient;
}
Získání řádků z tabulky
Třída TableClient obsahuje metodu s názvem Query, která umožňuje vybrat řádky z tabulky. Vzhledem k tomu, že se v tomto příkladu do metody předá žádné parametry, budou z tabulky vybrány všechny řádky.
Metoda také přebírá obecný parametr typu ITableEntity, který určuje, že data třídy modelu budou vrácena jako . V tomto případě se použije integrovaná třída TableEntity, což znamená, že metoda vrátí jako Query Pageable<TableEntity> výsledky kolekci.
public IEnumerable<WeatherDataModel> GetAllRows()
{
Pageable<TableEntity> entities = _tableClient.Query<TableEntity>();
return entities.Select(e => MapTableEntityToWeatherDataModel(e));
}
Třída TableEntity definovaná v balíčku má vlastnosti pro hodnoty klíče oddílu a klíče Azure.Data.Tables řádku v tabulce. Společně tyto dvě hodnoty jedinečného klíče pro řádek v tabulce. V této příkladové aplikaci se název meteorologické stanice (města) uloží v klíči oddílu a datum a čas pozorování se uloží v klíči řádku. Všechny ostatní vlastnosti (teplota, vlhkost, rychlost větru) se ukládají do slovníku v TableEntity objektu .
Obvykle se mapuje objekt TableEntity na objekt vlastní definice. Ukázková aplikace pro tento účel definuje třídu v WeatherDataModel adresáři Models. Tato třída má vlastnosti pro název stanice a datum pozorování, na které se bude klíč oddílu a klíč řádku mapovat, a poskytuje pro tyto hodnoty smysluplnější názvy vlastností. Potom použije slovník k uložení všech ostatních vlastností objektu. To je běžný vzor při práci se úložištěm Table, protože řádek může mít libovolný počet vlastností a chceme, aby naše objekty modelu dokázaly zachytit všechny. Tato třída obsahuje také metody pro zobrazení seznamu vlastností třídy.
public class WeatherDataModel
{
// Captures all of the weather data properties -- temp, humidity, wind speed, etc
private Dictionary<string, object> _properties = new Dictionary<string, object>();
public string StationName { get; set; }
public string ObservationDate { get; set; }
public DateTimeOffset? Timestamp { get; set; }
public string Etag { get; set; }
public object this[string name]
{
get => ( ContainsProperty(name)) ? _properties[name] : null;
set => _properties[name] = value;
}
public ICollection<string> PropertyNames => _properties.Keys;
public int PropertyCount => _properties.Count;
public bool ContainsProperty(string name) => _properties.ContainsKey(name);
}
Metoda MapTableEntityToWeatherDataModel se používá k mapování objektu TableEntity na WeatherDataModel objekt. Objekt TableEntity obsahuje vlastnost Keys pro získání všech názvů vlastností obsažených v tabulce objektu (ve podstatě názvy sloupců pro tento řádek v tabulce). Metoda mapuje přímo vlastnosti , , a a pak pomocí vlastnosti iteruje nad ostatními vlastnostmi v objektu a mapuje je na objekt minus vlastnosti, které již byly přímo MapTableEntityToWeatherDataModel PartitionKey RowKey Timestamp Etag Keys TableEntity WeatherDataModel namapovány.
Upravte kód v MapTableEntityToWeatherDataModel metodě tak, aby odpovídal následujícímu bloku kódu.
public WeatherDataModel MapTableEntityToWeatherDataModel(TableEntity entity)
{
WeatherDataModel observation = new WeatherDataModel();
observation.StationName = entity.PartitionKey;
observation.ObservationDate = entity.RowKey;
observation.Timestamp = entity.Timestamp;
observation.Etag = entity.ETag.ToString();
var measurements = entity.Keys.Where(key => !EXCLUDE_TABLE_ENTITY_KEYS.Contains(key));
foreach (var key in measurements)
{
observation[key] = entity[key];
}
return observation;
}
Filtrování řádků vrácených z tabulky
Pokud chcete filtrovat řádky vrácené z tabulky, můžete do metody Query předat řetězec filtru ve stylu OData. Pokud byste například chtěli získat všechny údaje o počasí v Chicagu mezi půlnocí 1. července 2021 a půlnocí 2. července 2021 (včetně), předáte následující řetězec filtru.
PartitionKey eq 'Chicago' and RowKey ge '2021-07-01 12:00 AM' and RowKey le '2021-07-02 12:00 AM'
Všechny operátory filtru OData můžete zobrazit na webu OData v části Filtr možnosti systémového dotazu.
V příkladu aplikace je objekt navržený tak, aby FilterResultsInputModel zachytil všechna kritéria filtru poskytnutá uživatelem.
public class FilterResultsInputModel : IValidatableObject
{
public string PartitionKey { get; set; }
public string RowKeyDateStart { get; set; }
public string RowKeyTimeStart { get; set; }
public string RowKeyDateEnd { get; set; }
public string RowKeyTimeEnd { get; set; }
[Range(-100, +200)]
public double? MinTemperature { get; set; }
[Range(-100,200)]
public double? MaxTemperature { get; set; }
[Range(0, 300)]
public double? MinPrecipitation { get; set; }
[Range(0,300)]
public double? MaxPrecipitation { get; set; }
}
Když je tento objekt předán metodě ve třídě , vytvoří řetězec filtru pro každou hodnotu vlastnosti, která GetFilteredRows TableService není null. Pak vytvoří kombinovaný řetězec filtru spojením všech hodnot s klauzulí "and". Tento kombinovaný řetězec filtru se předá metodě Query objektu TableClient a vrátí se pouze řádky, které odpovídají řetězci filtru. Podobnou metodu můžete v kódu použít k vytvoření vhodných řetězců filtru podle požadavků vaší aplikace.
public IEnumerable<WeatherDataModel> GetFilteredRows(FilterResultsInputModel inputModel)
{
List<string> filters = new List<string>();
if (!String.IsNullOrEmpty(inputModel.PartitionKey))
filters.Add($"PartitionKey eq '{inputModel.PartitionKey}'");
if (!String.IsNullOrEmpty(inputModel.RowKeyDateStart) && !String.IsNullOrEmpty(inputModel.RowKeyTimeStart))
filters.Add($"RowKey ge '{inputModel.RowKeyDateStart} {inputModel.RowKeyTimeStart}'");
if (!String.IsNullOrEmpty(inputModel.RowKeyDateEnd) && !String.IsNullOrEmpty(inputModel.RowKeyTimeEnd))
filters.Add($"RowKey le '{inputModel.RowKeyDateEnd} {inputModel.RowKeyTimeEnd}'");
if (inputModel.MinTemperature.HasValue)
filters.Add($"Temperature ge {inputModel.MinTemperature.Value}");
if (inputModel.MaxTemperature.HasValue)
filters.Add($"Temperature le {inputModel.MaxTemperature.Value}");
if (inputModel.MinPrecipitation.HasValue)
filters.Add($"Precipitation ge {inputModel.MinTemperature.Value}");
if (inputModel.MaxPrecipitation.HasValue)
filters.Add($"Precipitation le {inputModel.MaxTemperature.Value}");
string filter = String.Join(" and ", filters);
Pageable<TableEntity> entities = _tableClient.Query<TableEntity>(filter);
return entities.Select(e => MapTableEntityToWeatherDataModel(e));
}
Vložení dat pomocí objektu TableEntity
Nejjednodušší způsob, jak přidat data do tabulky, je pomocí objektu TableEntity. V tomto příkladu jsou data mapována ze vstupního objektu modelu na objekt TableEntity. Vlastnosti vstupního objektu představující název meteorologické stanice a datum a čas pozorování se mapují na vlastnosti PartitionKey a RowKey, které společně tvoří jedinečný klíč pro řádek v tabulce. Další vlastnosti objektu vstupního modelu se pak mapují na vlastnosti slovníku objektu TableEntity. Nakonec se k vložení dat do tabulky použije metoda AddEntity objektu TableClient.
Upravte třídu InsertTableEntity v příkladové aplikaci tak, aby obsahovala následující kód.
public void InsertTableEntity(WeatherInputModel model)
{
TableEntity entity = new TableEntity();
entity.PartitionKey = model.StationName;
entity.RowKey = $"{model.ObservationDate} {model.ObservationTime}";
// The other values are added like a items to a dictionary
entity["Temperature"] = model.Temperature;
entity["Humidity"] = model.Humidity;
entity["Barometer"] = model.Barometer;
entity["WindDirection"] = model.WindDirection;
entity["WindSpeed"] = model.WindSpeed;
entity["Precipitation"] = model.Precipitation;
_tableClient.AddEntity(entity);
}
Upsertování dat pomocí objektu TableEntity
Pokud se pokusíte vložit řádek do tabulky s kombinací klíče oddílu a klíče řádku, která už v této tabulce existuje, zobrazí se chyba. Z tohoto důvodu je při přidávání řádků do tabulky často vhodnější použít metodu UpsertEntity místo metody AddEntity. Pokud už v tabulce existuje kombinace klíče oddílu a klíče řádku, metoda UpsertEntity aktualizuje stávající řádek. V opačném případě se řádek přidá do tabulky.
public void UpsertTableEntity(WeatherInputModel model)
{
TableEntity entity = new TableEntity();
entity.PartitionKey = model.StationName;
entity.RowKey = $"{model.ObservationDate} {model.ObservationTime}";
// The other values are added like a items to a dictionary
entity["Temperature"] = model.Temperature;
entity["Humidity"] = model.Humidity;
entity["Barometer"] = model.Barometer;
entity["WindDirection"] = model.WindDirection;
entity["WindSpeed"] = model.WindSpeed;
entity["Precipitation"] = model.Precipitation;
_tableClient.UpsertEntity(entity);
}
Vložení nebo upsertování dat s vlastnostmi proměnných
Jednou z výhod používání služby Cosmos DB rozhraní API pro tabulky je, že pokud objekt načtený do tabulky obsahuje nové vlastnosti, tyto vlastnosti se automaticky přičtou do tabulky a hodnoty uložené v Cosmos DB. Pokud chcete přidat sloupce jako v tradiční databázi, není nutné spouštět příkazy DDL, jako je ALTER TABLE.
Tento model poskytuje vaší aplikaci flexibilitu při práci se zdroji dat, které mohou přidávat nebo upravovat data, která se mají v průběhu času zachytává, nebo když různé vstupy do vaší aplikace poskytují různá data. V ukázkové aplikaci můžeme simulovat meteorologické stanice, která odesílá nejen základní data o počasí, ale také některé další hodnoty. Při prvním uložení objektu s těmito novými vlastnostmi do tabulky se do tabulky automaticky přičtou odpovídající vlastnosti (sloupce).
V ukázkové aplikaci je třída sestavena z interního slovníku pro podporu jakékoli ExpandableWeatherObject sady vlastností objektu. Tato třída představuje typický vzor pro, když objekt musí obsahovat libovolnou sadu vlastností.
public class ExpandableWeatherObject
{
public Dictionary<string, object> _properties = new Dictionary<string, object>();
public string StationName { get; set; }
public string ObservationDate { get; set; }
public object this[string name]
{
get => (ContainsProperty(name)) ? _properties[name] : null;
set => _properties[name] = value;
}
public ICollection<string> PropertyNames => _properties.Keys;
public int PropertyCount => _properties.Count;
public bool ContainsProperty(string name) => _properties.ContainsKey(name);
}
Pokud chcete takový objekt vložit nebo upsertovat pomocí rozhraní API pro tabulky, namapování vlastností rozbalitelného objektu na objekt TableEntity a podle potřeby použijte metody AddEntity nebo UpsertEntity v objektu TableClient.
public void InsertExpandableData(ExpandableWeatherObject weatherObject)
{
TableEntity entity = new TableEntity();
entity.PartitionKey = weatherObject.StationName;
entity.RowKey = weatherObject.ObservationDate;
foreach (string propertyName in weatherObject.PropertyNames)
{
var value = weatherObject[propertyName];
entity[propertyName] = value;
}
_tableClient.AddEntity(entity);
}
public void UpsertExpandableData(ExpandableWeatherObject weatherObject)
{
TableEntity entity = new TableEntity();
entity.PartitionKey = weatherObject.StationName;
entity.RowKey = weatherObject.ObservationDate;
foreach (string propertyName in weatherObject.PropertyNames)
{
var value = weatherObject[propertyName];
entity[propertyName] = value;
}
_tableClient.UpsertEntity(entity);
}
Aktualizace entity
Entity je možné aktualizovat voláním metody UpdateEntity u objektu TableClient. Vzhledem k tomu, že entita (řádek) uložená pomocí rozhraní API pro tabulky může obsahovat libovolnou sadu vlastností, je často užitečné vytvořit aktualizační objekt založený na objektu Dictionary podobně jako ExpandableWeatherObject dříve. V tomto případě je jediným rozdílem přidání vlastnosti, která se používá pro řízení souběžnosti Etag během aktualizací.
public class UpdateWeatherObject
{
public Dictionary<string, object> _properties = new Dictionary<string, object>();
public string StationName { get; set; }
public string ObservationDate { get; set; }
public string Etag { get; set; }
public object this[string name]
{
get => (ContainsProperty(name)) ? _properties[name] : null;
set => _properties[name] = value;
}
public ICollection<string> PropertyNames => _properties.Keys;
public int PropertyCount => _properties.Count;
public bool ContainsProperty(string name) => _properties.ContainsKey(name);
}
V ukázkové aplikaci je tento objekt předán UpdateEntity metodě ve TableService třídě . Tato metoda nejprve načte existující entitu z rozhraní API pro tabulky pomocí metody GetEntity na objektu TableClient. Pak tento objekt entity aktualizuje a pomocí UpdateEntity metody aktualizace uloží do databáze. Všimněte si, že metoda UpdateEntity přebírá aktuální Etag objektu, aby se ujistila, že se objekt od počátečního načtení nezměnil. Pokud chcete entitu aktualizovat bez ohledu na to, můžete metodě předat Etag.Any UpdateEntity hodnotu .
public void UpdateEntity(UpdateWeatherObject weatherObject)
{
string partitionKey = weatherObject.StationName;
string rowKey = weatherObject.ObservationDate;
// Use the partition key and row key to get the entity
TableEntity entity = _tableClient.GetEntity<TableEntity>(partitionKey, rowKey).Value;
foreach (string propertyName in weatherObject.PropertyNames)
{
var value = weatherObject[propertyName];
entity[propertyName] = value;
}
_tableClient.UpdateEntity(entity, new ETag(weatherObject.Etag));
}
Odebrání entity
Pokud chcete entitu z tabulky odebrat, zavolejte metodu DeleteEntity u objektu TableClient s klíčem oddílu a klíčem řádku objektu.
public void RemoveEntity(string partitionKey, string rowKey)
{
_tableClient.DeleteEntity(partitionKey, rowKey);
}
7. Spuštění kódu
Spusťte ukázkovou aplikaci pro interakci s Cosmos DB rozhraní API pro tabulky. Při prvním spuštění aplikace nebudou k dispozici žádná data, protože tabulka je prázdná. Pomocí libovolného tlačítka v horní části aplikace přidejte data do tabulky.
Výběrem tlačítka Vložit pomocí entity tabulky se otevře dialogové okno, ve které můžete vložit nebo upsertovat nový řádek pomocí objektu TableEntity .
Výběrem tlačítka Vložit pomocí rozbalitelných dat se zobrazí dialogové okno, které vám umožní vložit objekt s vlastními vlastnostmi, což demonstruje, jak Cosmos DB rozhraní API pro tabulky v případě potřeby automaticky přidá do tabulky vlastnosti (sloupce). Pomocí tlačítka Přidat vlastní pole můžete přidat jednu nebo více nových vlastností a předvést tuto funkci.
Pomocí tlačítka Vložit ukázková data načtěte ukázková data do vaší Cosmos DB.
Výběrem položky Filtrovat výsledky v horní nabídce přejděte na stránku Výsledky filtru. Na této stránce vyplňte kritéria filtru, abyste předvedli, jak lze vytvořit klauzuli filtru a předat ji do Cosmos DB rozhraní API pro tabulky.
Vyčištění prostředků
Až s ukázkovou aplikací skončíte, měli byste ze svého účtu Azure odebrat všechny prostředky Azure související s tímto článkem. Můžete to provést odstraněním skupiny prostředků.
Skupinu prostředků je možné odstranit pomocí Azure Portal následujícím způsobem.
Další kroky
V tomto rychlém startu jste se seznámili s postupem vytvoření databázového účtu Azure Cosmos DB, vytvoření tabulky pomocí Průzkumníka dat a spuštění aplikace. Teď můžete zadávat dotazy na svá data pomocí rozhraní API tabulky.