Kom igång med Azure Table Storage och Azure Cosmos DB Table API med hjälp av F#

Azure Table Storage är en tjänst som lagrar strukturerade NoSQL-data i molnet. Table Storage är en nyckel- och attributdatabas med en schemalös design. Eftersom Table Storage är schemalös är det enkelt att anpassa dina data i takt med att programmets behov förändras. Åtkomsten till data är snabb och kostnadseffektiv för alla typer av program. Kostnaden för Table Storage är normalt sett betydligt lägre än för motsvarande volymer med traditionell SQL.

Du kan använda Table Storage för att lagra flexibla datauppsättningar, till exempel användardata för webbprogram, adressböcker, enhetsinformation och andra typer av metadata som din tjänst kräver. Du kan lagra valfritt antal enheter i en tabell, och ett lagringskonto kan innehålla valfritt antal tabeller, upp till lagringskontots kapacitetsgräns.

Azure Cosmos DB tillhandahåller tabell-API:et för program som är skrivna för Azure Table Storage och som kräver premiumfunktioner som:

  • Nyckelfärdig global distribution.
  • Dedikerat dataflöde över hela världen.
  • Latensvärden på enstaka millisekunder vid 99:e percentilen.
  • Garanterat hög tillgänglighet.
  • Automatisk sekundär indexering.

Program som skrivits för Azure Table Storage kan migreras till Azure Cosmos DB med hjälp av tabell-API:et utan kodändringar och dra nytta av premiumfunktioner. Tabell-API:et har klient-SDK:er tillgängliga för .NET, Java, Python och Node.js.

Mer information finns i Introduktion till Azure Cosmos DB Table API. De här självstudierna använder anslutningssträng för att autentisera med Azure. För optimal säkerhet bör du använda Microsoft Entra-ID med hanterade identiteter.

Om den här självstudiekursen

Den här självstudien visar hur du skriver F#-kod för att utföra några vanliga uppgifter med hjälp av Azure Table Storage eller Azure Cosmos DB Table API, inklusive att skapa och ta bort en tabell samt infoga, uppdatera, ta bort och göra frågor mot tabelldata.

Förutsättningar

Om du vill använda den här guiden måste du först skapa ett Azure Storage-konto eller Ett Azure Cosmos DB-konto.

Skapa ett F#-skript och starta interaktivT F#

Exemplen i den här artikeln kan användas i antingen ett F#-program eller ett F#-skript. Skapa ett F#-skript genom att skapa en fil med .fsx tillägget, till exempel tables.fsx, i din F#-utvecklingsmiljö.

Så här kör du skript

F# Interactive, dotnet fsi, kan startas interaktivt eller startas från kommandoraden för att köra ett skript. Kommandoradssyntaxen är

> dotnet fsi [options] [ script-file [arguments] ]

Lägga till paket i ett skript

#r nuget:package name Använd sedan för att installera Azure.Data.Tables paketet och open namnrymderna. Såsom

> #r "nuget: Azure.Data.Tables"
open Azure.Data.Tables

Lägga till namnrymdsdeklarationer

Lägg till följande open-instruktioner överst i tables.fsx-filen:

open System
open Azure
open Azure.Data.Tables // Namespace for Table storage types

Hämta din Azure Storage-anslutningssträng

Om du ansluter till tjänsten Azure Storage Table, behöver du din anslutningssträng för den här handledningen. Du kan kopiera anslutningssträng från Azure Portal. Mer information om anslutningssträng finns i Konfigurera anslutningssträngar för lagring.

Hämta din Azure Cosmos DB-anslutningssträng

Om du ansluter till Azure Cosmos DB behöver du ha din anslutningssträng för den här tutorialen. Du kan kopiera anslutningssträng från Azure Portal. I Azure Portal går du till Inställningar>anslutningssträng i Cosmos DB-kontot och väljer knappen Kopiera för att kopiera den primära anslutningssträngen.

I självstudien anger du din anslutningssträng i skriptet, som i följande exempel:

let storageConnString = "..." // fill this in from your storage account

Skapa tabelltjänstklienten

Med TableServiceClient klassen kan du hämta tabeller och entiteter i Table Storage. Här är ett sätt att skapa tjänstklienten:

let tableClient = TableServiceClient storageConnString

Nu är det dags att skriva kod som läser data från och skriver data till Table Storage.

Skapa en tabell

Det här exemplet illustrerar hur du skapar en tabell om den inte redan finns:

// Retrieve a reference to the table.
let table = tableClient.GetTableClient "people"

// Create the table if it doesn't exist.
table.CreateIfNotExists () |> ignore

Lägga till en entitet i en tabell

En entitet måste ha en typ som implementerar ITableEntity. Du kan utöka ITableEntity på vilket sätt du vill, men din typ måste ha en parameterlös konstruktor. Endast egenskaper som har både get och set lagras i azure-tabellen.

En entitets partitions- och radnyckel identifierar unikt entiteten i tabellen. Det går snabbare att fråga entiteter med samma partitionsnyckel än entiteter som har olika partitionsnycklar, men skalbarheten och möjligheten att utföra parallella åtgärder är större med olika partitionsnycklar.

Här är ett exempel på en Customer som använder lastName som partitionsnyckel och firstName som radnyckel.

type Customer (firstName, lastName, email: string, phone: string) =
    interface ITableEntity with
        member val ETag = ETag "" with get, set
        member val PartitionKey = "" with get, set
        member val RowKey = "" with get, set
        member val Timestamp = Nullable() with get, set

    new() = Customer(null, null, null, null)
    member val Email = email with get, set
    member val PhoneNumber = phone with get, set
    member val PartitionKey = lastName with get, set
    member val RowKey = firstName with get, set

Lägg nu till Customer i tabellen. För att göra det kan vi använda metoden AddEntity().

let customer = Customer ("Walter", "Harp", "Walter@contoso.com", "425-555-0101")
table.AddEntity customer

Infoga en omgång med entiteter

Du kan infoga en batch med entiteter i en tabell med hjälp av en enda skrivåtgärd. Med batchbearbetningar kan du kombinera operationer till en enda exekvering, men de har vissa begränsningar:

  • Du kan utföra uppdateringar, borttagningar och infogningar i samma batchåtgärd.
  • En batchåtgärd kan innehålla upp till 100 entiteter.
  • Alla entiteter i en batchåtgärd måste ha samma partitionsnyckel.
  • Även om det är möjligt att utföra en fråga i en batchåtgärd måste det vara den enda åtgärden i batchen.

Här är en kod som kombinerar två infogningar i en batchåtgärd:

let customers =
    [
        Customer("Jeff", "Smith", "Jeff@contoso.com", "425-555-0102")
        Customer("Ben", "Smith", "Ben@contoso.com", "425-555-0103")
    ]

// Add the entities to be added to the batch and submit it in a transaction.
customers
|> List.map (fun customer -> TableTransactionAction (TableTransactionActionType.Add, customer))
|> table.SubmitTransaction

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 Query<T> objekt. Här filtrerar du efter entiteter där "Smith" är partitionsnyckeln.

table.Query<Customer> "PartitionKey eq 'Smith'"

Hämta ett intervall med enheter i en partition

Om du inte vill fråga efter alla entiteter i en partition kan du ange ett intervall genom att kombinera partitionsnyckelfiltret med ett radnyckelfilter. Här använder du två filter för att hämta alla entiteter i "Smith"-partitionen där radnyckeln (förnamnet) börjar med en bokstav tidigare än "M" i alfabetet.

table.Query<Customer> "PartitionKey eq 'Smith' and RowKey lt 'J'"

Hämta en enda entitet

Om du vill hämta en enskild, specifik entitet använder du GetEntityAsync för att ange kunden "Ben Smith". I stället för en samling får du tillbaka en Customer. Att ange både partitionsnyckeln och radnyckeln i en fråga är det snabbaste sättet att hämta en enskild entitet från tabelltjänsten.

let singleResult = table.GetEntity<Customer>("Smith", "Ben").Value

Nu skriver du ut resultatet:

// Evaluate this value to print it out into the F# Interactive console
singleResult

Uppdatera en entitet

Om du vill uppdatera en entitet hämtar du den från tabelltjänsten, ändrar entitetsobjektet och sparar sedan ändringarna i tabelltjänsten igen med hjälp av en TableUpdateMode.Replace åtgärd. Detta gör att entiteten ersätts helt på servern, såvida inte entiteten på servern har ändrats sedan den hämtades, i vilket fall åtgärden misslyckas. Det här felet är för att förhindra att din applikation oavsiktligt skriver över ändringar från andra källor.

singleResult.PhoneNumber <- "425-555-0103"
try
    table.UpdateEntity (singleResult, ETag "", TableUpdateMode.Replace) |> ignore
    printfn "Update succeeded"
with
| :? RequestFailedException as e ->
    printfn $"Update failed: {e.Status} - {e.ErrorCode}"

Utför en uppdatering eller insättning av en entitet

Ibland vet du inte om en entitet finns i tabellen. Och om det gör det behövs inte längre de aktuella värden som lagras i den. Du kan använda UpsertEntity metoden för att skapa entiteten eller ersätta den om den finns, oavsett dess tillstånd.

singleResult.PhoneNumber <- "425-555-0104"
table.UpsertEntity (singleResult, TableUpdateMode.Replace)

Gör en sökning efter en deluppsättning attribut hos en entitet

En tabellfråga kan bara hämta några egenskaper från en entitet i stället för alla. Den här tekniken, som kallas projektion, kan förbättra frågeprestanda, särskilt för stora entiteter. Här returnerar du endast e-postadresser med hjälp av Query<T> och Select. Projektion stöds inte i den lokala lagringsemulatorn, så den här koden körs bara när du använder ett konto i tabelltjänsten.

query {
    for customer in table.Query<Customer> () do
    select customer.Email
}

Hämta entiteter på sidor asynkront

Om du läser ett stort antal entiteter och vill bearbeta dem när de hämtas i stället för att vänta på att alla ska returneras kan du använda en segmenterad fråga. Här returnerar du resultat på sidor med hjälp av ett asynkront arbetsflöde så att körningen inte blockeras medan du väntar på att en stor uppsättning resultat ska returneras.

let pagesResults = table.Query<Customer> ()

for page in pagesResults.AsPages () do
    printfn "This is a new page!"
    for customer in page.Values do
        printfn $"customer: {customer.RowKey} {customer.PartitionKey}"

Ta bort en entitet

Du kan ta bort en entitet när du har hämtat den. Precis som vid uppdatering av en entitet misslyckas detta om entiteten har ändrats sedan du hämtade den.

table.DeleteEntity ("Smith", "Ben")

Ta bort en tabell

Du kan ta bort en tabell från ett lagringskonto. En tabell som har tagits bort kommer inte att kunna återskapas under en tid efter borttagningen.

table.Delete ()

Se även