QuickAzTables 0.0.4

There is a newer version of this package available.
See the version list below for details.
dotnet add package QuickAzTables --version 0.0.4
NuGet\Install-Package QuickAzTables -Version 0.0.4
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="QuickAzTables" Version="0.0.4" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add QuickAzTables --version 0.0.4
#r "nuget: QuickAzTables, 0.0.4"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install QuickAzTables as a Cake Addin
#addin nuget:?package=QuickAzTables&version=0.0.4

// Install QuickAzTables as a Cake Tool
#tool nuget:?package=QuickAzTables&version=0.0.4

QuickAzTables

Opinionated and minimal library to allow quick and easy use of Azure Table Storage with minimal code. This works best if you have a relatively small amount of data you'd like to store in Azure Tables. This library severely strips down the functionality from the official SDK, so the consumer has to deal with much less complexity, knowledge of the Table Storage requirements and its intricacies.

Assumptions

Your consuming code must conform to or accept below assumptions.

  • You have somewhat small amount of data to be stored.
  • All your data can be mapped to tables with known and stable partition and row keys for each entity.
  • If you have nested objects in your model, they can be JSON serialized with each JSON is 64KiB or smaller.
  • You don't care about advanced usage of table storage like ETags, If-Match queries, .etc. (If you need this functionality, you're better off using the official SDK directly.)
  • You are ok with either providing partition/row keys that are valid table storage keys or ok with the library sanitizing them by removing invalid chars, truncating keys that are too long .etc.
    • There is a utility function that allows validation of a given key and describing the issue (TableKey.Validate(key)) however the checks done here are not meant to be exhaustive. (see Table Storage docs for a definitive set of requirements.))

Intro

Imagine you want to store below in Azure Table Storage

public class Car {
    public string PlateNo { get; set; }
    public string City { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public DateTimeOffset BuildDate { get; set; }
    public Owner Owner { get; set; } // JSON serialized
}

public class Owner {
    public string Name { get; set; }
    ...
}

Initialization

Create an instance of TypedTableStore since the data is typed.

You can also use the underlying TableStore class if you don't have a type. Though you will have to provide your data using TableEntity type from Azure.Data.Tables SDK.

using QuickAzTables;

var store = new TypedTableStore<Car>(tableName: "Cars",
                               connectionString: "...", // can also use sasTokens
                               // optional selectors if your keys 
                               // can be derived from model, set to null otherwise
                               partitionKeySelector: (car) => car.City, 
                               rowKeySelector: (car) => car.PlateNo,
                               // createTableIfNotExists: true // default
                               
                               // invalidKeyCharReplacement: "" // default to omit 
                               // chars that are not valid in table keys.
                               );

// if you specified createTableIfNotExists: false
await store.CreateTableIfNotExists();

Storing

await store.StoreSingleAsync(new Car {...});

// If you don't want to use the key selectors or your keys 
// aren't derived from the model.

await store.StoreSingleAsync(new Car {...}, partitionKey, rowKey);
// this stores in the table. If you have a nested model 
// like Car.Owner, this will be JSON serialized and stored 
// in a property named __jsonFor_Owner

// or storing multiple
await store.StoreMultipleAsync(new List<Car> {...} );
// this will automatically group by partition (using partitionKeySelector), 
// and upload to table storage in batches. Currently 
// there's no API to store multiple items without 
// using key selectors.

Note that all the non standard properties will be saved under columns named "__jsonFor_{propertyName}". As long as the JSON is under the table storage property limits (about 64 KiB) this will work.

Retrive a Single Row (Point Query)

var car = await store.QuerySingleAsync(new Car {...});
// if (car is null) // handle missing row

// or
var car = await store.QuerySingleAsync(partitionKey, rowKey);
// if (car is null) // handle missing row

Querying Multiple Rows

// Query multiple rows
var cars=  await store.QueryAsync(new Car { /*specify 
enough props to infer either partition or row key*/ });
// selectors will be used to infer the keys

await foreach(var car in rows) {
  ...
}
// or 
var cars = await store.QueryAsync(partitionKey, rowKey);

If only the partition key was provided (or inferred using partitionKeySelector(match)) this will return all the rows in the specified partition.

If only the row key was provided (or inferred using rowKeySelector(match)) this will return all the matching rows in each partition.

Calls to Table Storage will be done in batches as the consuming code enumerates the resulting IAsyncEnumerable.

Want the whole table?

var rows = await RetrieveFullTable();

If you have a large amount of data in the table, consider partitioning it as this will download the whole table as you enumerate the IAsyncEnumerable.

Deleting

await store.DeleteSingleAsync(car);
// both keys must be inferrable.

// or 
await store.DeleteSingleAsync(partitionKey, rowKey);

// delete multiple 
await DeleteMultipleAsync(new List<Car>{...});
// all items in the list must be able to infer keys, 
// and all items must be in the same partition.

// or 

await DeleteMultipleInPartitionAsync(partitionKey, 
  new List<string> {/*row keys*/} );

Misc

Some other functionality is also available as static functions. These may be useful in some related cases.

  • TableStore.ListTables(...) lets you list the names of tables.
  • TableKey.Sanitize(key) returns a sanitized version of the given input that can be a partition or row key.
  • TableKey.Validate(key) returns a string explaining why the given string would fail as a partition or row key (or null if it is a valid key). Note that this checks if the actual number of bytes for the input exceeds the 1KiB limit, so avoid passing large strings to this for perf reasons.
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.0 304 1/16/2023
1.0.2 266 1/10/2023
1.0.1 271 12/29/2022
1.0.0 265 12/29/2022
0.0.4 363 12/29/2022
0.0.3 316 12/29/2022
0.0.2 310 12/29/2022
0.0.1 320 12/29/2022