Множественные условия фильтрации

Как установить несколько фильтров в хранилище таблиц 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 записей.

В соответствии с this doc из msdn, так как время от времени должно быть отформатировано.

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

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

Ответы

Ответ 1

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

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

Ответ 2

Как установить несколько фильтров в хранилище таблиц 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;
    }
}

Ответ 3

Я использую 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();

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

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

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

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

Ответ 4

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

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

Недопустимый код причины, потому что значение даты/времени должно быть введено в формате yyyy-MM-ddTHH:mm:ssZ. Поэтому ваш запрос должен быть:

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