Несколько условий фильтрации хранилище таблиц Azure

Как установить несколько фильтров в хранилище таблиц Azure?

это то, что я пробовал:

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);

это не работает, потому что TableQuery.CombineFilters() принимает только 3 параметра. И мне нужен дополнительный параметр для второго свидания.

моя вторая попытка:

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);

возвращает 400 bad request. Но если я удалю "datetime", он запускается, но не возвращает результатов, в то время как он должен вернуть несколько 100 записей.

по данным этой doc от msdn, именно так должно быть отформатировано время данных.

мой результат должен быть все записи между двумя датами.

как я могу это сделать?

5 ответов


сначала " и "ваш фильтр разделов с одним из фильтров даты, затем" и " промежуточный результат с другим фильтром даты.

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);

Как установить несколько фильтров в хранилище таблиц Azure?

мне было интересно то же самое. Я написал расширение класса TableQuery, которое отлично работает.

Это простое изменение, которое заставляет меня задуматься, если мы собираемся о запросе с несколькими фильтрами неправильно.

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;
    }
}

Я использую Хранилище Windows Azure 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();

вот сгенерированный запрос :

((PartitionKey eq 'partition1') и (метка времени ge datetime '2016-01-31T11:00:00Z')) и (метка времени le datetime'2016-02-01T11:00: 00Z')

вы можете заметить, что:

  • фильтры были объединены.
  • в даты были преобразованы в UTC.

просто хотел добавить еще один ответ.

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);

причина, по которой код выше не работает, заключается в том, что значение даты/времени должно быть введено в . Поэтому ваш запрос должен быть:

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);

просто обрабатывая случай нового запроса, который уже не имеет фильтра и основан на @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;
        }

а остальные следуют той же проверке, все может пойти лучше.