9

我最近进入了 C# / Azure 并且有一个小问题我想解决。该应用程序按预期工作,但我想重构一堆类,因为我确信有一个更简单的解决方案。

我目前有一堆函数可以从 Azure 中检索实体,这些实体仅在检索的类型方面有所不同,但最佳情况下我只想要一个像这样的类:

public static Object Do(string RowKey, string partitionKey, string tableName)
{
    var theTable = Connect.Initialize(tableName);
    var retrieveOperation = TableOperation.Retrieve(
                                      Base64.EncodeTo64(partitionKey),
                                      Base64.EncodeTo64(RowKey));

    var retrievedResult = theTable.Execute(retrieveOperation);

    if (retrievedResult.Result != null) {
        return retrievedResult.Result;
    }
     throw new ArgumentException(
                 String.Format("{0} not found in the Table", RowKey));
}

这本身就可以工作并检索所需的实体。但是,我不能在没有错误的情况下转换返回的对象。

我想将其转换为的对象类型实现了 TableEntity-Type 并匹配表中的结果。

我知道我可以将它投射到

TableOperation.Retrieve<Type>(...)

但我真的很想为此目的使用一个函数,这需要我在调用该函数时强制转换它。

我怀疑这个问题与 Result 是 DynamicTableEntity 类型的事实有关,但我不知道为什么。

有什么办法可以优雅地解决这个问题/有没有办法建立一个参数来保存我想要的类型?(我用“Type ...”试过,但这不起作用)。

4

4 回答 4

1

你可以尝试这样的事情:

return (Entity)retrievedResult.Result;

class Entity : TableEntity
{
    public string PartKey => PartitionKey;
    public string RowKey => RowKey;
}
于 2017-08-22T08:10:22.760 回答
1

试试这个,明确地将 TEntity 指定为 TableEntity 然后将其转换为广义的

public async Task<TEntity> Get<TEntity>(string tableName, string partitionKey, string rowkey) where TEntity : TableEntity, new()
    {
        var table = this._tableClient.GetTableReference(tableName);
        var result = await table.ExecuteAsync(TableOperation.Retrieve<TEntity>(partitionKey, rowkey));
        return (TEntity)result.Result;
    }
于 2021-07-23T10:25:05.457 回答
0

我遇到了同样的问题,我的演员失败的原因是因为该Retrieve操作没有获得我的类型所需的所有列;默认情况下,它只有 PartitionKey、RowKey(可能还有 ETag 等)

为了使我的演员成功,我在 Retrieve 调用中指定了额外的列:

// Define the additional columns we want, and pass them into Retrieve
var columns = new List<string>(){ "Name", "Status" };
var retrieve = TableOperation.Retrieve<MyEntity>(partitionKey, rowKey, columns);
var returnedObject = await cloudTable.ExecuteAsync(retrieve).Result

// The cast succeeds
var myThing = (MyEntity)returnedObject;

对于更灵活的方法,您的每个 TableEntity 子类型都可以有一个他们需要的列的静态列表public static List<string> Columns = new List<string>() { "Name", "Status" };

然后,为了使你的Do()通用,我认为它看起来像这样(未经测试,你可能需要做更多的铸造并查找一些通用魔法......):

public static T Do<T>(string RowKey, string partitionKey, string tableName)
{
    var theTable = Connect.Initialize(tableName);
    var retrieveOperation = TableOperation.Retrieve<T>(
                                      Base64.EncodeTo64(partitionKey),
                                      Base64.EncodeTo64(RowKey),
                                      T.Columns);

    var retrievedResult = theTable.Execute(retrieveOperation);

    if (retrievedResult.Result != null) {
        return retrievedResult.Result;
    }
     throw new ArgumentException(
                 String.Format("{0} not found in the Table", RowKey));
}

为了更好的完整性,你的每个 TableEntity 类也应该符合一个新的接口,比如ITableWithColumns规定 TableEntity 可以提供List<string> Columns如上所述的 a。

在我的博文Failure to cast an object from Azure TableOperation.Retrieve中有更多细节。

于 2018-05-08T16:56:51.437 回答
-5

您可以在 c# 中使用具有泛型类型的函数

参考这个链接

您还可以在此处参考 stackoverflow 示例

于 2014-06-30T10:33:43.883 回答