繁体   English   中英

从“WindowsAzure.Storage”迁移时,我应该为 Azure 表使用什么 package

[英]What package should I use for Azure Tables when migrating away from "WindowsAzure.Storage"

我目前正在将使用 ASP.NET WebApi 为 .NET Fx 4.8 编写的项目迁移到 .NET 5.0。 该项目大量使用 package WindowsAzure.Storage来访问 Azure 存储帐户上的 BLOB、表和队列。 这个 package 现在已经被弃用了一段时间,说明它已经被分成几个包。

对于队列和 Blob,我应该迁移到什么位置非常清楚。 但是,关于 Azure 表似乎有很多混淆。

  • First of all in the NuGet package WindowsAzure.Storage it states that the package to use for tables would be Microsoft.Azure.CosmosDB.Table . 这有点令人困惑,因为我一直认为“CosmosDB”与“Azure Tables”完全不同,但也许我错了。
  • 但是, Microsoft.Azure.CosmosDB.Table的描述指出此 package 处于维护模式,将被弃用。 我应该改用Microsoft.Azure.Cosmos.Table
  • Microsoft.Azure.Cosmos.Table但是很久没有更新了,而且 2.0.0 的预览版已经两年多了。 GitHub repo 上还有一个问题,专门询问该项目是否已死 - 没有答案。
  • 搜索后,我发现 package Azure.Data.Tables最接近我可能正在寻找的东西。 它已更新,看起来很活跃,并且似乎与其他存储包一致(版本号)。 只是命名有点偏离。 今年 6 月,MS 还发表了一篇博文,谈到这款 package 是全新的,所以我想这就是我要找的东西?

无论如何:我发现 Azure.Data.Tables 的APIWindowsAzure.Storage非常相似,我只需要在这里和那里进行一些调整。

但是我现在完全缺少的是QueryComparisonsTableQuery类。 他们刚刚走了吗? 有替代品吗?

要迁移的代码示例如下:

var part1 = 
  TableQuery.GenerateFilterConditionForGuid(
    nameof(SomeEntity.Id),
    QueryComparisons.Equal,
    idValue));
var part2 = 
  TableQuery.GenerateFilterConditionForGuid(
    nameof(SomeEntity.Category)
    QueryComparisons.Equal,
    category));
return TableQuery.CombineFilters(part1, TableOperators.And, part2);

我遇到了同样的问题。 是的,来自Microsoft.Azure.Cosmos.TablesTableQuery已经消失,并且文档中对TableOdataFilter的引用是无用的,因为它不存在。

看着这个,我发现使用Azure.Data.Tables package 方法查询 Azure 存储表的最简单方法是使用.Query<T>([predicate])方法 例如

TableClient customers;

var example = customers.Query<Customer>(c => c.Name == "Microsoft");

还有一个.QueryAsync<T>(..)异步版本。

如果您使用TableQuery构建查询,则没有直接的替代方法,但您可以使用PredicateBuilder之类的东西来组合.And().Or()表达式来创建谓词。

我修改了这个以创建一个流畅的版本:

    /// <summary>
    /// Helper class to build predicates fluently
    /// </summary>
    /// <remarks>
    /// Adapted from source: http://www.albahari.com/nutshell/predicatebuilder.aspx
    /// </remarks>
    public class PredicateBuilder<T>
    {
        private Expression<Func<T, bool>> expression;

        /// <summary>
        /// Add an OR clause
        /// </summary>
        /// <param name="expr">new expression</param>
        /// <returns></returns>
        public PredicateBuilder<T> Or(Expression<Func<T, bool>> expr)
        {
            if (expression == null)
                expression = expr;
            else
            {
                var invokedExpr = Expression.Invoke(expr, expression.Parameters.Cast<Expression>());
                expression = Expression.Lambda<Func<T, bool>>(Expression.OrElse(expression.Body, invokedExpr), expression.Parameters);
            }
            return this;
        }

        /// <summary>
        /// Add an AND clause
        /// </summary>
        /// <param name="expr">new expression</param>
        /// <returns></returns>
        public PredicateBuilder<T> And(Expression<Func<T, bool>> expr)
        {
            if (expression is null)
                expression = expr;
            else
            {
                var invokedExpr = Expression.Invoke(expr, expression.Parameters.Cast<Expression>());
                expression = Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expression.Body, invokedExpr), expression.Parameters);
            }
            return this;
        }

        /// <summary>
        /// Return resulting expression
        /// </summary>
        /// <returns></returns>
        public Expression<Func<T, bool>> ToPredicate()
        {
            if (expression is null)
                return (T value) => true;
            return expression;
        }
    }

示例用法:

var query = new PredicateBuilder<Customer>();

if(name != null)
  query.And(c => c.Name == name);

if (isActive == false)
  query.And(c => c.IsActive == false);

希望这可以帮助

您可能应该在该博客文章相关文档中进一步阅读:

查询表实体

TableClient 允许用户使用 OData 过滤器创建自定义查询。

string MyPK = "markers";
string MyRK = "id-001";
string filter = TableOdataFilter.Create($"PartitionKey eq {MyPK} or RowKey eq {MyRK}")

Pageable<TableEntity> entities = tableClient.Query<TableEntity>(filter: filter);

foreach (TableEntity entity in entities)
{
    Console.WriteLine($"{entity.GetString("Product")}: {entity.GetInteger("Count")}");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM