RSCG – TableStorage

RSCG – TableStorage    

name TableStorage
nuget https://www.nuget.org/packages/TableStorage/
link https://github.com/StevenThuriot/TableStorage
author Steven Thuriot

Generate resources for accessing Azure Table Storage

  

This is how you can use TableStorage .

The code that you start with is

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
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); 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
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

1
2
3
4
5
6
7
8
9
using System;
 
namespace TableStorage
{
    [AttributeUsage(AttributeTargets.Class)]
    public sealed class TableContextAttribute : Attribute
    {
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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  ="">&gt; _unknownTableSets = new System.Collections.Concurrent.ConcurrentDictionary<string  , tablestorage.tableset><t  ="">&gt;();
            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 =&gt;
                    {
                        ICreator creator = TableStorage.TableStorageSetup.BuildCreator(connectionString, configure);
 
                        return new DatabaseContext()
                        {
                            _creator = creator,
                            Employees = creator.CreateSet<test.employee>("Employees", null, null),
                        };
                    });
        }
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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)
        {
        }
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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 =&gt; 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&#91;arrayIndex++&#93; = 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