SujaySarma.Data.Azure.Tables
8.0.0
See the version list below for details.
dotnet add package SujaySarma.Data.Azure.Tables --version 8.0.0
NuGet\Install-Package SujaySarma.Data.Azure.Tables -Version 8.0.0
<PackageReference Include="SujaySarma.Data.Azure.Tables" Version="8.0.0" />
paket add SujaySarma.Data.Azure.Tables --version 8.0.0
#r "nuget: SujaySarma.Data.Azure.Tables, 8.0.0"
// Install SujaySarma.Data.Azure.Tables as a Cake Addin #addin nuget:?package=SujaySarma.Data.Azure.Tables&version=8.0.0 // Install SujaySarma.Data.Azure.Tables as a Cake Tool #tool nuget:?package=SujaySarma.Data.Azure.Tables&version=8.0.0
Sujay Sarma's Azure Tables Client SDK
(Azure Storage Tables, Azure Development Storage, Azurite & CosmosDB compatible)
Library | Current version |
---|---|
SujaySarma.Data.Azure.Tables | Version 8.0.0 |
About this library
Microsoft keeps changing the library names, calling conventions and provided APIs, too frequently for developers to have a stable and consistent environment to code against. This library is an attempt by me to provide both myself and other developers in the same boat overcome those limitations while writing maintainable and performant code.
While you can just use this library as a wrapper for Microsoft's Azure.Data.Tables
library, the true power of this library is
when you use its powerful ORM capabilities. Transform your .NET business objects (class
es or record
s) in the blink of an eye to
TableEntity
-ies and vice-versa. When you do so, you also get to leverage the powerful type-transformation and built-in Json serialization
capabilities.
Dependencies
This package only depends on whatever is the current Microsoft library of the day that provides the client APIs to interact with Azure Storage Tables and CosmosDB. Right now, that library is
Dependability and Trustworthiness
- All the code is MIT licensed and open source. Examine every aspect of what the library does.
- I use this library in tons of my applications, tools, etc. You can expect bugs to be swiftly fixed.
- Enhancements happen all the time.
- If you need help or spot an issue, file a ticket on the Issues section.
Usage
Write your .NET business object as a class
or record
. For example:
public class Person
{
public string LastName { get; set; }
public string FirstName { get; set; }
public DateTime DateOfBirth { get; set; }
//...
}
Let's say you want to store this object in an Azure Storage Table (or CosmosDB container) named People
, add the following to the top
of your class file:
using SujaySarma.Data.Azure.Tables.Attributes;
and add this attribute above your class declaration:
[Table("People")]
public class Person ...
For this table, Microsoft mandates that you define a PartitionKey
and a RowKey
that can be stored only as string
s. There are also
restrictions
on what characters are valid for these values.
To specify these fields, add the relevant attributes from our SujaySarma.Data.Azure.Tables.Attributes
namespace. Let's define our
LastName
property as the PartitionKey
and FirstName
as the RowKey
:
[PartitionKey]
public string LastName { get; set; }
[RowKey]
public string FirstName { get; set; }
We want to store the DateOfBirth
in a table column named DateOfBirth
:
[TableColumn("DateOfBirth")]
public DateTime DateOfBirth { get; set; }
Finally, let's add a property to this class named Hobbies
as a List<string>
. We cannot store such types directly in the underlying table.
Therefore, we need to tell the SDK to magically serialize it to Json and store that Json in the table.
[TableColumn("Hobbies", JsonSerialize = true)]
public List<string> Hobbies { get; set; } = new();
The completed class definition becomes:
[Table("People")]
public class Person
{
[PartitionKey]
public string LastName { get; set; }
[RowKey]
public string FirstName { get; set; }
[TableColumn("DateOfBirth")]
public DateTime DateOfBirth { get; set; }
[TableColumn("Hobbies", JsonSerialize = true)]
public List<string> Hobbies { get; set; } = new();
}
Let's instantiate an item and provide some data:
Person p = new()
{
LastName = "Doe",
FirstName = "John",
DateOfBirth = new DateTime(2000, 1, 1),
Hobbies = new() { "Painting", "Reading" }
};
Now, we need to store this in our tables. If you do not have one already, head over to the Azure Portal and create a new
Azure Storage account. Then from its Access Keys blade, copy the connection string
under key1
. The library provides exactly
one class AzureTablesContext
, which provides a connection-less paradigm to operate against the underlying Tables API. Initialize
it with the connection string from above.
AzureTablesContext tablesContext = new("<connection string>");
Of course, you can store the connection string in your Environment Variables or an appsettings.json or the KeyVault or wherever and use it from there.
You can also use the fluid-style initializers:
- To initialize with Development Storage (we are Azurite compatible!). Note that this will use HTTP (not httpS)!!!
AzureTablesContext tablesContext = AzureTablesContext.WithDevelopmentStorage();
- To initialize with provided connection string:
AzureTablesContext tablesContext = AzureTablesContext.WithConnectionString("<connection string>");
Insert the item we created into this storage.
tablesContext.Insert<Person>(p);
That's it. If you go to the Storage Browser blade of the storage account, you will find the People
table there with the data you
set above. Notice how the value of the Hobbies
column is the Json-serialized value of the .NET property.
To read it back:
Person? p2 = tablesContext.SelectOnlyResultOrNull<Person>(partitionKey: "Doe", rowKey: "John");
The return of that call will be a Null if it could not find the information requested. Examine the values of the properties in p2
to
confirm that all the values you stored earlier have been retrieved correctly.
NOTE: The Tables API stores DateTime values only as UTC. The SujaySarma.Data.Azure.Tables
(this) library automatically hard-codes
all DateTime
, DateTimeOffset
values to UTC while storing them. The value will not change, but it will be dealt with as 'UTC'. If you
perform Timezone conversions in your code, you will need to 'unconvert' the value returned from the table back to whatever its original
zone was:
DateTime dt = DateTime.SpecifyKind(p2.DateOfBirth, DateTimeKind.Local);
Asynchronous operations
As of v8.x, the SDK supports async
operations via the new xxxAsync()
methods such as InsertAsync
in the AzureTablesContext
class. However,
do note that the Async fetch operations (eg: SelectAsync<T>
) will return IAsyncEnumerable<T>
and you need to use your own async foreach()
for example
to loop through and fetch the results. To help, we do provide two extension methods (they are in the AzureTablesContextExtensions
class but will attach to
any IAsyncEnumerable<T>
instance):
async Task<bool> AnyAsync<T>(this IAsyncEnumerable<T> e, Predicate<T>? validation = null)
This method checks if any item in the IAsyncEnumerable
matches the provided condition in the same way as the System.Linq
method Any()
works.
async Task<List<T>> ToListAsync<T>(this IAsyncEnumerable<T> e)
This method accepts an IAsyncEnumerable<T>
and returns a List<T>
. It performs the await foreach()
for you.
Some typical gotchas
- When storing arrays/lists/collections of Enums as serialized Json, ensure you set the
JsonConverter(typeof(JsonStringEnumConverter))
attribute on theenum
definition and not on the property! You set the converter attribute on the property only if it is a single value (not an array/collection).
Powerful features
- You can store almost any type into a table using this library. If it does not store properly, just add a
JsonSerialize = true
to theTableColumn
attribute.
Happy coding!
Product | Versions 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. |
-
net6.0
- Azure.Data.Tables (>= 12.7.1)
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 |
---|---|---|
9.1.0 | 98 | 6/26/2024 |
8.5.0 | 149 | 12/19/2023 |
8.0.0 | 461 | 1/9/2023 |
7.4.0 | 411 | 9/16/2022 |
7.3.0 | 409 | 9/8/2022 |
7.2.0 | 412 | 9/8/2022 |
7.0.0 | 400 | 8/28/2022 |
6.4.0 | 463 | 8/4/2022 |
6.3.5 | 573 | 3/24/2022 |
6.3.0 | 369 | 9/9/2021 |
6.2.2 | 326 | 8/20/2021 |
6.2.0 | 356 | 8/18/2021 |
6.0.0 | 441 | 8/13/2021 |
5.1.5 | 439 | 6/30/2021 |
5.1.0 | 378 | 5/6/2021 |
5.0.0 | 366 | 5/2/2021 |
Version 8.0.0 - Bug fixes and Enhancements:
1. Performance optimizations
2. Retired the old StorageConnection and Command classes. Now the only way to use is via the AzureTablesContext class.
3. Added async support. Almost every method has an async equivalent. See readme for details.
4. bug fixed: Fixed problem with dev storage connection string to enable it to work with Azurite engine.