Azure表存储在.NET Core中的CreateQuery

19

我正在将原本针对.NET Framework 4.6.2的类库移植到.NET Core 1.1。

看起来在.NET Core中,一些在.NET Framework版本中可用的方法不再存在。其中两个这样的方法是table.CreateQuerytable.ExecuteQuery

这里有一个现有的函数,在使用CreateQuery时会出现错误:

public T Get<T>(string partitionKey, string rowKey, string tableName) where T : ITableEntity, new()
            => getTable(tableName).CreateQuery<T>().Where(r => r.PartitionKey == partitionKey && r.RowKey == rowKey).FirstOrDefault();

在 .NET Core 中如何创建查询?


在我的情况下,谓词中使用了方法而不是标准运算符(==、!=等)。 - gsscoder
2个回答

20
根据这个问题:Missing syncronous methods for dotnet core?,NetCore / Netstandard支持尚未包括API的同步实现。
由于CreateQuery和ExecuteQuery都是同步方法,因此我们无法在.NET Core中使用它们,您只能使用ExecuteQuerySegmentedAsync、TableQuery、Fluent API并处理它返回的继续标记。更多细节,请参考以下代码:
更新:
public static void Main(string[] args)
{
    var result = Get<BookTest3>("Aut_Fantasy", "Cert-0000000020", "DifferenetPartitionTest");
    Console.Write(result.PartitionKey);
    Console.Read();
}

public static T Get<T>(string partitionKey, string rowKey, string tableName) where T : ITableEntity, new()
{
    CloudTable table = ConnectToTable(tableName);
    TableQuery<T> employeeQuery = new TableQuery<T>().Where(
        TableQuery.CombineFilters(
            TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey),
            TableOperators.And,
            TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThan, rowKey))
        ).Take(1);
    var re = new T();
        TableContinuationToken continuationToken = null;
    do
    {
        Task<TableQuerySegment<T>> employees = table.ExecuteQuerySegmentedAsync(employeeQuery, continuationToken);
        TableQuerySegment<T> employeess = employees.Result;
        re= employeess.FirstOrDefault();
        continuationToken = employeess.ContinuationToken;
    } while (continuationToken != null);
    return re;
}

希望这些提示能够对您有所帮助。
更新代码:
public static void Main(string[] args)
{
    var tas = Get<BookTest3>("Aut_Fantasy", "Cert-0000000020", "DifferenetPartitionTest");
    var result = tas.Result;
    Console.Write(result.PartitionKey);
    Console.Read();
}

public async static Task<T> Get<T>(string partitionKey, string rowKey, string tableName) where T : ITableEntity, new()
{
    //new T();
    CloudTable table = ConnectToTable(tableName);
    TableQuery<T> employeeQuery = new TableQuery<T>().Where(
        TableQuery.CombineFilters(
            TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey),
            TableOperators.And,
            TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThan, rowKey))
        ).Take(1);
    var re = new T();
        TableContinuationToken continuationToken = null;
    do
    {
        var employees = await table.ExecuteQuerySegmentedAsync(employeeQuery, continuationToken);

        re = employees.FirstOrDefault();
        continuationToken = employees.ContinuationToken;
    } while (continuationToken != null);
    return re;
}

如何让我的方法通用化,以便我可以读取任何实体,例如Get<T>,而不仅仅是BookTest3?我一直在到处寻找一些例子,但却找不到。我的代码中的GET方法必须在任何场景下都能使用——也就是说它应该能够返回任何对象类型。 - Sam
谢谢。我非常感激。我认为在 Get 方法中第一行的 new T(); 不是必要的,对吗? - Sam
我还有一个问题,如果可以的话。即使我们使用 ExecuteQuerySegmentedAsync() 进行异步调用,但在方法内部我们没有使用 await 或是在方法头中使用 async Task<T>。我的业务层方法通常都是 async 方法,所以即使我们在其中进行异步调用,不使用 await 调用 Get<T> 会感觉有点尴尬。 - Sam
据我所知,我们也可以在方法头中使用异步 Task<T> 并在方法内容中使用 await,这与我的代码是相同的,只是稍微改动了一些代码。 - Brando Zhang
我们如何使用LINQ进行查询? - Alex Gordon
根据 https://azure.microsoft.com/pl-pl/resources/samples/azure-cosmos-db-table-dotnet-getting-started/,选择 Microsoft.Azure.CosmosDB.Table NuGet,因为它支持 CosmosDB 和 Azure Tables。 - Voodu

11
我会在这篇文章中添加这些方便的扩展方法 :)
public static async System.Threading.Tasks.Task<IEnumerable<DynamicTableEntity>> ExecuteQueryAsync(this CloudTable table, TableQuery query)
{
    TableContinuationToken token = null;
    var retVal = new List<DynamicTableEntity>();
    do
    {
        var results = await table.ExecuteQuerySegmentedAsync(query, token);
        retVal.AddRange(results.Results);
        token = results.ContinuationToken;
    } while (token != null);

    return retVal;
}

public static async System.Threading.Tasks.Task<IEnumerable<T>> ExecuteQueryAsync<T>(this CloudTable table, TableQuery<T> query) where T : ITableEntity, new()
{
    TableContinuationToken token = null;
    var retVal = new List<T>();
    do
    {
        var results = await table.ExecuteQuerySegmentedAsync(query, token);
        retVal.AddRange(results.Results);
        token = results.ContinuationToken;
    } while (token != null);

    return retVal;
}

他们会给你相同的功能,只是将方法名更改为ExecuteQueryASYNC。

请给出一个如何使用它们的示例 - Alex Gordon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接