Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure Table Storage - Generic download for any type extending ITableEntity

I have four custom data types, each of which extends ITableEntity, which is part of the WindowsAzure.Storage package.

Right now, I have four different methods for downloading data from the Azure Table storage. Each follows this format:

public List<MyCustomEntity> DownloadMyCustomEntities(string tableId)
{
    // Reference the CloudTable object
    CloudTable table = tableClient.GetTableReference(tableId);

    TableQuery<MyCustomEntity> query = new TableQuery<MyCustomEntity>();
    return new List<MyCustomEntity>(table.ExecuteQuery(query));
}

Instead of having one of these methods for each of my custom entity types, I am trying to create one shared function. I'm hoping this is possible, as all of my custom types inherit from ITableEntity.

Here is what I tried:

public List<TableEntity> DownloadAnyEntity(string tableId)
{
    // Reference the CloudTable object
    CloudTable table = tableClient.GetTableReference(tableId);

    TableQuery<TableEntity> query = new TableQuery<TableEntity>();
    return new List<TableEntity>(table.ExecuteQuery(query));
}

I've tried this with TableEntity and ITableEntity, but I keep getting errors. For TableEntity, my error is that no cast exists to the type I actually need (when I call the DownloadAnyEntity method), whereas I feel it should be implicit since it is an extension of ITableEntity.

For ITableEntity, I get an error that ExecuteQuery input must be a non-abstract type with a public parameterless constructor. All of my four custom types have public parameterless constructors.

I feel like the issue I'm seeing is more to do with not fully understanding inheritance, more so that it being Azure Table Storage specific. Any pointers much appreciated.

I've largely been following this documentation, but there is no example for a non type-specific entity download method.

like image 989
Azarantara Avatar asked Oct 08 '18 04:10

Azarantara


1 Answers

You could make the DownloadAnyEntity method generic with constraints on type parameter

public List<T> DownloadAnyEntity<T>(string tableId) where T: ITableEntity, new()
{
    // Reference the CloudTable object
    var tableRef = tableClient.GetTableReference(tableId);

    var query = new TableQuery<T>();
    return tableRef.ExecuteQuery(query).ToList();
}

This method can then be called for any type that inherits from the ITableEntity and has an public emtpy constructor (The ExecuteQuery method demands an empty construtor in order to create the entities)

like image 150
Marcus Höglund Avatar answered Sep 28 '22 12:09

Marcus Höglund