TypedSpark.NET

Funky Azure Data Table Extensions

Functions to easily interact with Azure table storage and Cosmos Table API. The library has been developed using C# with functional style programming.

The library uses Microsoft's Azure.Data.Tables package to perform data operations.

The library separates commands and queries, and provides separate methods to be used easily on your data tables.

🎉 Features

💡 Separation of command and query operations.

💡 Query and command responses are strongly typed with clear intentions of what will be returned.

💡 Support for either managed identity or connection string through dependency injection.

💡 Use single named table service client for commands and queries (ICommandService and IQueryService).

💡 Use multiple named table service clients with CommandExtensions and QueryExtensions.

🎉 Query Usages

🔆 With partition and row key

Use the GetEntityAsync method in IQueryService for this.

var op = await queryService.GetEntityAsync<ProductDataModel>(
    "ProductsDomain", // named service client
    "products", // table name // table name
    "TECH",
    "PROD1",
    new CancellationToken()
    );

// the operation returns the possible outputs, which you can pick and choose to operate on.
op.Response switch
{
    QueryResult.SingleResult<ProductDataModel> r => ,// do things
    QueryResult.EmptyResult e => ,// do things        
    QueryResult.QueryFailedResult f => ,// handle things,
    _ => ,// handle things more
};

🔆 With LINQ expressions

Use the GetEntityListAsync in IQueryService for this.

var op = await queryService.GetEntityListAsync<ProductDataModel>(
    "ProductsDomain", // named service client
    "products", // table name
    x => x.Category == "TECH", // filter to apply as LINQ expression
    new CancellationToken()
);

// the operation returns the possible outputs, which you can pick and choose to operate on.
op.Response switch
{
    QueryResult.CollectionResult<ProductDataModel> products => ,// do things,
    QueryResult.SingleResult<ProductDataModel> s => ,// do things,
    QueryResult.EmptyResult e => ,// do things,             
    QueryResult.QueryFailedResult f => ,// handle things
    _ => // handle things more
};

🎉 Command Usages

🔆 Upsert an entity

var productDataModel = ProductDataModel.New("TECH", "PROD1", 259.99d);
var commandOp = await commandService.UpsertAsync(
    "ProductsDomain", // named service client
    "products", // table name
    productDataModel, // table entity to upsert
    new CancellationToken()
);

// the operation returns the possible outputs, which you can pick and choose to operate on.
commandOp.Operation switch
  {
      CommandOperation.CommandSuccessOperation _ => ,// do things
      CommandOperation.CommandFailedOperation f => ,// handle things
      _ => // handle things more
  }

🔆 Update an entity

Use the UpdateAsync method in ICommandService for this.

var updateOp = await commandService.UpdateAsync(
    category,
    table,
    ProductDataModel.New("TECH", "PROD1", 100.50d),
    new CancellationToken()
);

updateOp.Operation switch
{
    CommandOperation.CommandSuccessOperation => ,// do things
    CommandOperation.CommandFailedOperation f => , // handle things
    _ => // handle things more
};

Using the library in your solutions

🔆 Install package and configure

Install the Funky.Azure.DataTable.Extensions from nuget.
Then register it as a dependency either using RegisterTablesWithConnectionString or RegisterTablesWithManagedIdentity.

This will allow you to register the TableServiceClient as a named instance.

In the below example ProductsDomain is the named client.

// If you are using an ASP.NET application
builder.Services.RegisterTablesWithConnectionString(
            "ProductsDomain",
            "[Connection string for the storage account]"
        );

// This is from the sample console application in the examples section.
var host = Host.CreateDefaultBuilder()
    .ConfigureServices(services =>
    {
        services.RegisterTablesWithConnectionString(
         "ProductsDomain",
         "[Connection string for the storage account]"
        );
    })
    .Build();
    

🔆 Inject the dependencies IQueryService or ICommandService or both to your class.

Use this approach ONLY if you need only a single table service client for both queries and commands.

Refer 🎉 Command Usages for commands, and 🎉 Query Usages for queries using this approach.

🔆 OR register your own named IAzureClientFactory<TableServiceClient> dependency and use QueryExtensions and CommandExtensions.

Differences between table storage, and cosmos table API

There are some behaviour in Azure table storage, and in Azure Cosmos table API. Please refer the official documentation for this

Attributions

Icons created by juicy_fish