简体   繁体   English

多个过滤条件Azure表存储

[英]Multiple filter conditions Azure table storage

How can I set multiple filters on a Azure Table Storage? 如何在Azure表存储上设置多个过滤器?

This is what I've tried: 这就是我尝试过的:

string partitionFilter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "partition1");
string date1 = TableQuery.GenerateFilterCondition("Date", QueryComparisons.GreaterThanOrEqual, "31-8-2013T14:15:14Z");
string date2 = TableQuery.GenerateFilterCondition("Date", QueryComparisons.LessThanOrEqual, "31-8-2013T14:15:14Z");
string finalFilter = TableQuery.CombineFilters(partitionFilter, TableOperators.And, date1);

This doesn't work because TableQuery.CombineFilters() only takes 3 parameters. 这不起作用,因为TableQuery.CombineFilters()只需要3个参数。 And I need an extra parameter for the 2nd date. 我需要第二个日期的额外参数。

My second try: 我的第二次尝试:

string filter = "PartitionKey eq 'partition1' and Date ge datetime'31-8-2013T14:15:14Z' and Date lt datetime'31-8-2013T14:19:10Z'";
TableQuery<CustomEntity> query = new TableQuery<CustomEntity>().Where(filter).Take(5);

This returns 400 bad request . 这会返回400 bad request But if I remove the 'datetime' it runs but returns no results while it should return a few 100 records. 但是如果我删除了'datetime'它会运行但是返回没有结果,而它应该返回几个100条记录。

According to this doc from msdn, that is how datetimes should be formatted. 根据msdn的这个文档,这就是应该如何格式化日期时间。

My result should be all records that are between two dates. 我的结果应该是两个日期之间的所有记录。

How can I make this work? 我怎样才能做到这一点?

First "and" your partition filter with one of the date filters, then "and" the intermediate result with the other date filter. 首先使用其中一个日期过滤器“和”分区过滤器,然后使用其他日期过滤器“和”中间结果。

string date1 = TableQuery.GenerateFilterConditionForDate(
                   "Date", QueryComparisons.GreaterThanOrEqual,
                   DateTimeOffsetVal);
string date2 = TableQuery.GenerateFilterConditionForDate(
                   "Date", QueryComparisons.LessThanOrEqual,
                   DateTimeOffsetVal);
string finalFilter = TableQuery.CombineFilters(
                        TableQuery.CombineFilters(
                            partitionFilter,
                            TableOperators.And,
                            date1),
                        TableOperators.And, date2);

How can I set multiple filters on a Azure Table Storage? 如何在Azure表存储上设置多个过滤器?

I was wondering the same thing. 我想知道同样的事情。 I wrote an extension to the TableQuery class which works fine. 我写了一个TableQuery类的扩展,工作正常。

It's an easy change which makes me wonder if we are going about querying with multiple filters incorrectly. 这是一个简单的更改,让我想知道我们是否正在使用多个过滤器进行错误查询。

public static class TableQueryExtensions 
{
    public static TableQuery<TElement> AndWhere<TElement>(this TableQuery<TElement> @this, string filter)
    {
        @this.FilterString = TableQuery.CombineFilters(@this.FilterString, TableOperators.And, filter);
        return @this;
    }

    public static TableQuery<TElement> OrWhere<TElement>(this TableQuery<TElement> @this, string filter)
    {
        @this.FilterString = TableQuery.CombineFilters(@this.FilterString, TableOperators.Or, filter);
        return @this;
    }

    public static TableQuery<TElement> NotWhere<TElement>(this TableQuery<TElement> @this, string filter)
    {
        @this.FilterString = TableQuery.CombineFilters(@this.FilterString, TableOperators.Not, filter);
        return @this;
    }
}

I am using Windows Azure Storage 7.0.0 and you can use Linq query so that you don't need to combine filters anymore: 我正在使用Windows Azure Storage 7.0.0 ,您可以使用Linq查询,这样您就不再需要组合过滤器了:

// filter dates for test
var startDate = DateTime.Parse("01/02/2016 12:00:00 AM"); 
var endDate = DateTime.Parse("02/02/2016 12:00:00 AM");

// Get the cloud table
var cloudTable = GetCloudTable();

// Create a query: in this example I use the DynamicTableEntity class
var query = cloudTable.CreateQuery<DynamicTableEntity>()
        .Where(d => d.PartitionKey == "partition1"
               && d.Timestamp >= startDate && d.Timestamp <= endDate);

// Execute the query
var result = query.ToList();

Here is the generated query : 这是生成的查询:

((PartitionKey eq 'partition1') and (Timestamp ge datetime'2016-01-31T11:00:00Z')) and (Timestamp le datetime'2016-02-01T11:00:00Z') ((PartitionKey eq'partition1')和(Timestamp ge datetime'2016-01-31T11:00:00Z'))和(Timestamp le datetime'2016-02-01T11:00:00Z')

You can notice that: 你可以注意到:

  • The filters have been combined. 过滤器已合并。
  • The dates have been converted to UTC. 日期已转换为UTC。

Just wanted to add one more answer. 只想添加一个答案。

string filter = "PartitionKey eq 'partition1' and Date ge datetime'31-8-2013T14:15:14Z' and Date lt datetime'31-8-2013T14:19:10Z'";
TableQuery<TablePost> query = new TableQuery<TablePost>().Where(filter).Take(5);

The reason code above is failing is because the date/time value must be entered in yyyy-MM-ddTHH:mm:ssZ format. 上面的原因代码失败是因为日期/时间值必须以yyyy-MM-ddTHH:mm:ssZ格式输入。 So your query should be: 所以你的查询应该是:

string filter = "(PartitionKey eq 'partition1') and (Date ge datetime'2013-08-31T14:15:14Z' and Date lt datetime'2013-08-31T14:19:10Z')";
TableQuery<TablePost> query = new TableQuery<TablePost>().Where(filter).Take(5);

Just handling the case of a new query that does not have a filter already and based on @LivingOnACloud, I would rather write it this way: 只是处理一个没有过滤器且基于@LivingOnACloud的新查询的情况,我宁愿这样写:

 public static TableQuery<TElement> AndWhere<TElement>(this TableQuery<TElement> query, string filter)
            where TElement : ITableEntity,new ()
        {
            if (query.FilterString.IsNullOrEmpty())
            {
                query.FilterString =  filter;
            }
            else
            {
                query.FilterString = TableQuery.CombineFilters(query.FilterString, TableOperators.And, filter);
            }
            return query;
        }

And the rest follow the same check, things can go nicer. 其余的都按照相同的检查,事情可以更好。

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

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