Skip to content

Instantly share code, notes, and snippets.

@SamVanhoutte
Last active January 2, 2020 18:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SamVanhoutte/4a43f35684d6cb3c867f6eab1454c18e to your computer and use it in GitHub Desktop.
Save SamVanhoutte/4a43f35684d6cb3c867f6eab1454c18e to your computer and use it in GitHub Desktop.
Generic table transmitter class
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Table;
using TableStorage.Abstractions.TableEntityConverters;
using Traiders.Storage.Configuration;
namespace Storage.Adapters.Tablestorage
{
public abstract class TableTransmitter<T> where T : new()
{
private StorageSettings _settings;
private CloudStorageAccount _storageAccount;
private IDictionary<string, CloudTable> _loadedTables = new Dictionary<string, CloudTable>();
private string _tableName;
public TableTransmitter(StorageSettings settings, string tableName)
{
_settings = settings;
_tableName = tableName;
}
private CloudStorageAccount Account
{
get
{
if (_storageAccount == null)
{
_storageAccount = new CloudStorageAccount(
new StorageCredentials(_settings.AccountName, _settings.AccountKey), true);
}
return _storageAccount;
}
}
private async Task<CloudTable> GetTable()
{
if (!_loadedTables.ContainsKey(_tableName))
{
var table = Account.CreateCloudTableClient().GetTableReference(_tableName);
await table.CreateIfNotExistsAsync();
_loadedTables.Add(_tableName, table);
}
return _loadedTables[_tableName];
}
public async Task<T> GetItem(string partitionKey, string rowKey)
{
if (string.IsNullOrEmpty(rowKey))
{
throw new KeyNotFoundException($"Trying to get entity with empty rowkey from table {_tableName}");
}
//Table
var table = await GetTable();
//Operation
var operation = TableOperation.Retrieve(partitionKey, rowKey);
//Execute
var result = await table.ExecuteAsync(operation);
if (result.Result != null)
{
var resultEntity = result.Result as DynamicTableEntity;
return resultEntity.FromTableEntity<T>();
}
return default(T);
}
public async Task<List<T>> GetItems(string partitionKey)
{
//Table
var table = await GetTable();
var query = new TableQuery();
var entities = new List<T> { };
foreach (var entity in await table.ExecuteQuerySegmentedAsync(query, new TableContinuationToken()))
{
var resultEntity = entity as DynamicTableEntity;
entities.Add(resultEntity.FromTableEntity<T>());
}
return entities;
}
public async Task Insert(T entity, string partitionKey, string rowKey)
{
try
{
if (string.IsNullOrEmpty(rowKey))
{
throw new KeyNotFoundException($"Trying to insert entity with empty rowkey in table {_tableName}:\r\n{PrintEntity(entity)}");
}
//Table
var table = await GetTable();
var tableEntity = entity.ToTableEntity(partitionKey, rowKey);
//Operation
var operation = TableOperation.Insert(tableEntity);
//Execute
await table.ExecuteAsync(operation);
}
catch (StorageException se)
{
throw;
}
}
public async Task Update(T entity, string partitionKey, string rowKey)
{
if (string.IsNullOrEmpty(rowKey))
{
throw new KeyNotFoundException($"Trying to update entity with empty rowkey in table {_tableName}:\r\n{PrintEntity(entity)}");
}
//Table
var table = await GetTable();
var tableEntity = entity.ToTableEntity(partitionKey, rowKey);
//Operation
var operation = TableOperation.InsertOrReplace(tableEntity);
//Execute
await table.ExecuteAsync(operation);
}
public string PrintEntity(T entity)
{
var output = new StringBuilder();
foreach (var prop in entity.GetType().GetProperties())
{
var type = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
output.AppendLine($"- {prop.Name}:{prop.GetValue(entity, null)}");
}
return output.ToString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment