CoreHelpersPlus.WindowsAzure.Storage.Table
6.5.1-CI-20250704-191431
See the version list below for details.
dotnet add package CoreHelpersPlus.WindowsAzure.Storage.Table --version 6.5.1-CI-20250704-191431
NuGet\Install-Package CoreHelpersPlus.WindowsAzure.Storage.Table -Version 6.5.1-CI-20250704-191431
<PackageReference Include="CoreHelpersPlus.WindowsAzure.Storage.Table" Version="6.5.1-CI-20250704-191431" />
<PackageVersion Include="CoreHelpersPlus.WindowsAzure.Storage.Table" Version="6.5.1-CI-20250704-191431" />
<PackageReference Include="CoreHelpersPlus.WindowsAzure.Storage.Table" />
paket add CoreHelpersPlus.WindowsAzure.Storage.Table --version 6.5.1-CI-20250704-191431
#r "nuget: CoreHelpersPlus.WindowsAzure.Storage.Table, 6.5.1-CI-20250704-191431"
#:package CoreHelpersPlus.WindowsAzure.Storage.Table@6.5.1-CI-20250704-191431
#addin nuget:?package=CoreHelpersPlus.WindowsAzure.Storage.Table&version=6.5.1-CI-20250704-191431&prerelease
#tool nuget:?package=CoreHelpersPlus.WindowsAzure.Storage.Table&version=6.5.1-CI-20250704-191431&prerelease
! NOTICE THIS IS A CUSTOM BUILD OF AzureStorageTable that contains the following additional features:
- Multiple Types in the same table (Base objects)
AzureStorageTable
This projects implements an abstraction for Azure Storage Tables to use POCOs because deriving every entity from ITableEntity or TableEntity looks like a step backwards. The current implementation is intended to be an abstraction to store every existing entity into Azure Table Store.
There are two different principals implemented. The first allows to define an external mapping structure between the existing model and the required fields in Azure Table, e.g. Partition and RowKey. The second option is to decorate existing models with attributes to map the properties to partition and rowkey.
Installation
Install-Package CoreHelpers.WindowsAzure.Storage.Table
Manual Entity Mapper
// create a new user model
var user = new UserModel() { FirstName = "Egon", LastName = "Mueller", Contact = "em@acme.org" };
using (var storageContext = new StorageContext(storageKey, storageSecret))
{
// configure the entity mapper
storageContext.AddEntityMapper(typeof(UserModel), new DynamicTableEntityMapper() { TableName = "UserProfiles", PartitionKeyPropery = "Contact", RowKeyProperty = "Contact" });
// ensure the table exists
storageContext.CreateTable<UserModel>();
// inser the model
storageContext.MergeOrInsert<UserModel>(user);
// query all
var result = storageContext.Query<UserModel>();
foreach (var r in result)
{
Console.WriteLine(r.FirstName);
}
}
Attribute Based Entity Mapper
Decorate your existing model
[Storable()]
public class UserModel2
{
[PartitionKey]
[RowKey]
public string Contact { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Configure and use the Storage Context
// create a new user model
var user = new UserModel2() { FirstName = "Egon", LastName = "Mueller", Contact = "em@acme.org" };
using (var storageContext = new StorageContext(storageKey, storageSecret))
{
// ensure we are using the attributes
storageContext.AddAttributeMapper();
// ensure the table exists
storageContext.CreateTable<UserModel2>();
// inser the model
storageContext.MergeOrInsert<UserModel2>(user);
// query all
var result = storageContext.Query<UserModel2>();
foreach (var r in result)
{
Console.WriteLine(r.FirstName);
}
}
Virtual Partition and Row-Keys
When implementing storage schemes in Azure Table sometimes the partition or the row key are combinations out for two or more properties. Because of that the Azure Storage Table components supports virtual partition and row key attributes as follows:
[Storable()]
[VirtualPartitionKey("{{Value1}}-{{Value2}}")]
[VirtualRowKey("{{Value2}}-{{Value3}}")]
public class VirtualPartKeyDemoModel
{
public string Value1 { get; set; }
public string Value2 { get; set; }
public string Value3 { get; set; }
}
Virtual Array Attributes
When storing arrays in Azure Table store there are two options. The first option is to store it as a JSON payload and the second option is to expand the array with his items to separate properties, e.g.
{ DataElements: [1,2,3,4] }
becomes
DE00 | DE01 | DE02 | DE03 |
---|---|---|---|
1 | 2 | 3 | 4 |
in Azure Table Store with the following code:
[Storable(Tablename: "VArrayModels")]
public class VArrayModel
{
[PartitionKey]
[RowKey]
public string UUID { get; set; }
[VirtualList(PropertyFormat: "DE{{index}}", Digits: 2)]
public List<int> DataElements { get; set; } = new List<int>();
}
Virtual Dictionary Attributes
When storing dictionaries in Azure Table store there are two options. The first option is to store it as a JSON payload and the second option is to expand the dictionary with his items to separate properties in Azure Table Store with the following code:
[Storable(Tablename: "VDictionaryModels")]
public class VDictionaryModel
{
[PartitionKey]
[RowKey]
public string UUID { get; set; }
[VirtualDictionary(PropertyPrefix: "DE")]
public Dictionary<string, int> DataElements { get; set; } = new Dictionary<string, int>();
}
Store Enum as String Attribute
The store enum as string attribute allows to store enum values as string in Azure Table Store with the following code:
[Storable(Tablename: "EnumModel")]
public class EnumtModel
{
public enum TestEnum
{
First,
Second
}
[PartitionKey]
[RowKey]
public string UUID { get; set; }
[StoreEnumAsString]
public TestEnum Data { get; set; };
}
Store as JSON Object Attribute
The store as JSON attribute allows to store refenrenced objects as json payload for a specific property
[Storable(Tablename: "JObjectModel")]
public class JObjectModel
{
[PartitionKey]
[RowKey]
public string UUID { get; set; }
[StoreAsJsonObject]
public Dictionary<string, string> Data { get; set; } = new Dictionary<string, string>();
}
Store Multiple Objects Types in the same Table
If multiple objects share a common base class, it can be used to store them in the same table. The base class must be decorated with the Storable attribute with the TypeField
parameter set. It is best practice to NOT include the type field in the model.
[Storable(TypeField = "Type")]
public class BaseModel
{
[PartitionKey]
public string P { get; set; } = "Partition01";
[RowKey]
public string R { get; set; } = String.Empty;
}
public class MultipleModels1 : MultipleModelsBase
{
public string Model1Field { get; set; } = String.Empty;
}
public class MultipleModels2 : MultipleModelsBase
{
public string Model2Field { get; set; } = String.Empty;
}
When saving and querying it is important to use the base class as the generic type.
using (var storageContext = new StorageContext(storageKey, storageSecret))
{
storageContext.AddAttributeMapper();
storageContext.CreateTable<BaseModel>();
storageContext.MergeOrInsert<BaseModel>(new MultipleModels1() { R = "Row01", Model1Field = "Model1Field" });
storageContext.MergeOrInsert<BaseModel>(new MultipleModels2() { R = "Row02", Model2Field = "Model2Field" });
var result = storageContext.Query<BaseModel>();
foreach (var r in result)
{
Console.WriteLine(r.GetType().Name);
}
}
Related tables
It is possible to automatically load related tables, either lazily or eagerly. In order to load lazily simply pack the object in the Lazy<>
type.
[Storable(Tablename: "JObjectModel")]
public class Model
{
[PartitionKey]
[RowKey]
public string UUID { get; set; }
public string UserId {get; set; }
//This is the rowkey of the OtherModel
public string OtherModel { get; set; }
//Partition key must be specified explicitly, rowkey defaults to the name of the type (here: OtherModel)
[RelatedTable("UserId")]
public Lazy<OtherModel> OtherModelObject { get; set; }
}
It is possible to specify the rowkey explicitly:
[Storable(Tablename: "JObjectModel")]
public class Model
{
[PartitionKey]
[RowKey]
public string UUID { get; set; }
public string UserId {get; set; }
public string OtherModelId { get; set; }
[RelatedTable("UserId", RowKey="OtherModelId")]
public OtherModel OtherModel { get; set; }
}
If neither the rowkey or the partition key is the name of a property of the object they are used directly as strings, and obviously to reduce the possible causes of errors it is recommended to use the nameof
:
[Storable(Tablename: "Models")]
public class Model
{
[PartitionKey]
[RowKey]
public string UUID { get; set; }
public string OtherModelId { get; set; }
[RelatedTable(nameof(UUID), RowKey=nameof(OtherModelId))]
public Lazy<OtherModel> OtherModel { get; set; }
}
Contributing to Azure Storage Table
Fork as usual and go crazy!
Contributors Thank you to the following wonderful people for contributing to Azure Storage Table:
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 is compatible. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 is compatible. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.8
- Azure.Data.Tables (>= 12.8.0)
- CoreHelpersPlus.WindowsAzure.Storage.Table.Abstractions (>= 6.5.1-CI-20250704-191431)
- Handlebars.Net (>= 2.1.2)
- Newtonsoft.Json (>= 13.0.1)
- System.Linq.Parallel (>= 4.3.0)
- System.Linq.Queryable (>= 4.3.0)
-
.NETStandard 2.0
- Azure.Data.Tables (>= 12.8.0)
- CoreHelpersPlus.WindowsAzure.Storage.Table.Abstractions (>= 6.5.1-CI-20250704-191431)
- Handlebars.Net (>= 2.1.2)
- Newtonsoft.Json (>= 13.0.1)
- System.Linq.Parallel (>= 4.3.0)
- System.Linq.Queryable (>= 4.3.0)
-
.NETStandard 2.1
- Azure.Data.Tables (>= 12.8.0)
- CoreHelpersPlus.WindowsAzure.Storage.Table.Abstractions (>= 6.5.1-CI-20250704-191431)
- Handlebars.Net (>= 2.1.2)
- Newtonsoft.Json (>= 13.0.1)
- System.Linq.Parallel (>= 4.3.0)
- System.Linq.Queryable (>= 4.3.0)
-
net8.0
- Azure.Data.Tables (>= 12.8.0)
- CoreHelpersPlus.WindowsAzure.Storage.Table.Abstractions (>= 6.5.1-CI-20250704-191431)
- Handlebars.Net (>= 2.1.2)
- Newtonsoft.Json (>= 13.0.1)
- System.Linq.Parallel (>= 4.3.0)
- System.Linq.Queryable (>= 4.3.0)
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 |
---|---|---|
7.0.0-CI-20250729-181356 | 145 | 7/29/2025 |
7.0.0-CI-20250724-200738 | 460 | 7/24/2025 |
6.5.1-CI-20250704-194631 | 89 | 7/4/2025 |
6.5.1-CI-20250704-191431 | 66 | 7/4/2025 |
6.3.2-CI-20241219-104640 | 190 | 12/19/2024 |
6.3.2-CI-20241010-123249 | 74 | 10/10/2024 |
6.3.2-CI-20240822-092140 | 217 | 8/22/2024 |
6.3.2-CI-20240819-204146 | 104 | 8/19/2024 |
6.3.2-CI-20231129-125929 | 233 | 11/29/2023 |
6.3.2-CI-20231128-102549 | 77 | 11/28/2023 |
6.3.2-CI-20231127-221214 | 82 | 11/27/2023 |