RSCG – TableStorage
Generate resources for accessing Azure Table Storage
This is how you can use TableStorage .
The code that you start with is
<project sdk="Microsoft.NET.Sdk">
<propertygroup>
<outputtype>Exe</outputtype>
<targetframework>net8.0</targetframework>
<implicitusings>enable</implicitusings>
<nullable>enable</nullable>
</propertygroup>
<itemgroup>
<packagereference version="12.13.1" include="Azure.Storage.Blobs">
<packagereference version="12.1.0" include="Azure.Storage.Files.Shares">
<packagereference version="12.11.1" include="Azure.Storage.Queues">
<packagereference version="1.5.0" include="Microsoft.Extensions.Azure">
<packagereference version="8.0.0" include="Microsoft.Extensions.DependencyInjection">
<packagereference version="4.2.1" include="TableStorage">
</packagereference>
<propertygroup>
<emitcompilergeneratedfiles>true</emitcompilergeneratedfiles>
<compilergeneratedfilesoutputpath>$(BaseIntermediateOutputPath)\GX</compilergeneratedfilesoutputpath>
</propertygroup>
</packagereference>
The code that you will use is
using Microsoft.Extensions.DependencyInjection;
using test;
/*Visual Studio version Azurite executable location
Visual Studio Community 2022 C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator
Visual Studio Professional 2022 C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator
Visual Studio Enterprise 2022 C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator
*/
var serviceProvider = new ServiceCollection()
.AddDatabaseContext("UseDevelopmentStorage=true")
.BuildServiceProvider();
DatabaseContext db = serviceProvider.GetRequiredService<databasecontext>();
Employee? e=new ();
e.Name = "Andrei Ignat";
e.PartitionKey = "1";
e.RowKey = Guid.NewGuid().ToString();
await db.Employees.AddEntityAsync(e);
e = await db.Employees.GetEntityAsync(e.PartitionKey, e.RowKey);
Console.WriteLine(e?.Name);
using TableStorage;
namespace test;
[TableContext]
public partial class DatabaseContext
{
public TableSet<employee>? Employees { get; set; }
}
[TableSet]
[TableSetProperty(typeof(bool), "Enabled")]
[TableSetProperty(typeof(string), "Name")]
public partial class Employee
{
}
The code that is generated is
using System;
namespace TableStorage
{
[AttributeUsage(AttributeTargets.Class)]
public sealed class TableContextAttribute : Attribute
{
}
}
using Microsoft.Extensions.DependencyInjection;
using TableStorage;
using System;
#nullable disable
namespace test
{
public static class DatabaseContextExtensions
{
public static IServiceCollection AddDatabaseContext(this IServiceCollection services, string connectionString, Action<tablestorage.tableoptions> configure = null)
{
DatabaseContext.Register(services, connectionString, configure);
return services;
}
}
partial class DatabaseContext
{
private TableStorage.ICreator _creator { get; init; }
private static class TableSetCache<t>
where T : class, Azure.Data.Tables.ITableEntity, new()
{
private static System.Collections.Concurrent.ConcurrentDictionary<string , tablestorage.tableset><t ="">> _unknownTableSets = new System.Collections.Concurrent.ConcurrentDictionary<string , tablestorage.tableset><t ="">>();
public static TableStorage.TableSet<t> GetTableSet(TableStorage.ICreator creator, string tableName)
{
return _unknownTableSets.GetOrAdd(tableName, creator.CreateSet<t>);
}
}
public TableSet<t> GetTableSet<t>(string tableName)
where T : class, Azure.Data.Tables.ITableEntity, new()
{
return TableSetCache<t>.GetTableSet(_creator, tableName);
}
public static void Register(IServiceCollection services, string connectionString, Action<tablestorage.tableoptions> configure = null)
{
services.AddSingleton(s =>
{
ICreator creator = TableStorage.TableStorageSetup.BuildCreator(connectionString, configure);
return new DatabaseContext()
{
_creator = creator,
Employees = creator.CreateSet<test.employee>("Employees", null, null),
};
});
}
}
}
using System;
namespace TableStorage
{
[AttributeUsage(AttributeTargets.Class)]
public sealed class TableSetAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class TableSetPropertyAttribute : Attribute
{
public TableSetPropertyAttribute(Type type, string name)
{
}
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class PartitionKeyAttribute : Attribute
{
public PartitionKeyAttribute(string name)
{
}
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class RowKeyAttribute : Attribute
{
public RowKeyAttribute(string name)
{
}
}
}
using Microsoft.Extensions.DependencyInjection;
using TableStorage;
using System.Collections.Generic;
using System;
#nullable disable
namespace test
{
[System.Diagnostics.DebuggerDisplay(@"Employee \{ {PartitionKey}, {RowKey} \}")]
partial class Employee : IDictionary<string , object="">, Azure.Data.Tables.ITableEntity
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTimeOffset? Timestamp { get; set; }
public Azure.ETag ETag { get; set; }
[System.Runtime.Serialization.IgnoreDataMember] public bool Enabled { get; set; }
[System.Runtime.Serialization.IgnoreDataMember] public string Name { get; set; }
public object this[string key]
{
get
{
switch (key)
{
case "PartitionKey": return PartitionKey;
case "RowKey": return RowKey;
case "Timestamp": return Timestamp;
case "odata.etag": return ETag.ToString();
case "Enabled": return Enabled;
case "Name": return Name;
default: return null;
}
}
set
{
switch (key)
{
case "PartitionKey": PartitionKey = value?.ToString(); break;
case "RowKey": RowKey = value?.ToString(); break;
case "Timestamp": Timestamp = (System.DateTimeOffset?)value; break;
case "odata.etag": ETag = new Azure.ETag(value?.ToString()); break;
case "Enabled": Enabled = (bool) value; break;
case "Name": Name = (string) value; break;
}
}
}
public ICollection<string> Keys => new string[] { "PartitionKey", "RowKey", "Timestamp", "odata.etag", "Enabled", "Name", };
public ICollection<object> Values => new object[] { PartitionKey, RowKey, Timestamp, ETag.ToString(), Enabled, Name, }; public int Count => 6; public bool IsReadOnly => false; public void Add(string key, object value) { this[key] = value; } public void Add(KeyValuePair<string, object> item) { this[item.Key] = item.Value; } public void Clear() { Enabled = default(bool); Name = default(string); } public bool Contains(KeyValuePair<string, object> item) { if (TryGetValue(item.Key, out var value)) { return value == item.Value; } return false; } public bool ContainsKey(string key) { switch (key) { case "PartitionKey": case "RowKey": case "Timestamp": case "odata.etag": case "Enabled": case "Name": return true; default: return false; } } public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) { if (array == null) { throw new System.ArgumentNullException("array"); } if ((uint)arrayIndex > (uint)array.Length) { throw new System.IndexOutOfRangeException(); } if (array.Length - arrayIndex < Count) { throw new System.ArgumentException(); } foreach (var item in this) { array[arrayIndex++] = item; } } public IEnumerator<KeyValuePair<string, object>> GetEnumerator() { yield return new KeyValuePair<string, object>("PartitionKey", PartitionKey); yield return new KeyValuePair<string, object>("RowKey", RowKey); yield return new KeyValuePair<string, object>("Timestamp", Timestamp); yield return new KeyValuePair<string, object>("odata.etag", ETag.ToString()); yield return new KeyValuePair<string, object>("Enabled", Enabled); yield return new KeyValuePair<string, object>("Name", Name); } public bool Remove(string key) { if (ContainsKey(key)) { this[key] = null; return true; } return false; } public bool Remove(KeyValuePair<string, object> item) { if (Contains(item)) { this[item.Key] = null; return true; } return false; } public bool TryGetValue(string key, out object value) { switch (key) { case "PartitionKey": value = PartitionKey; return true; case "RowKey": value = RowKey; return true; case "Timestamp": value = Timestamp; return true; case "odata.etag": value = ETag; return true; case "Enabled": value = Enabled; return true; case "Name": value = Name; return true; default: value = null; return false; } } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); } } }
Code and pdf at https://ignatandrei.github.io/RSCG_Examples/v2/docs/TableStorage