2013-08-31 13 views
15

Jak ustawić wiele filtrów w magazynie magazynu Azure?Warunki wielu filtrów Przechowywanie tabel Azure

To co próbowałem:

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

To nie działa, ponieważ TableQuery.CombineFilters() trwa tylko 3 parametry. I potrzebuję dodatkowego parametru dla drugiej daty.

Moja druga próba:

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

ta zwraca 400 bad request. Ale jeśli usunę "datetime", uruchomi się, ale nie zwróci żadnych wyników, podczas gdy powinien zwrócić kilka 100 rekordów.

Według dokumentu this doc z msdn, w ten sposób należy sformatować datetime.

Mój wynik powinien być wszystkimi rekordami pomiędzy dwiema datami.

Jak mogę to ułatwić?

Odpowiedz

28

Najpierw "i" filtr partycji z jednym z filtrów daty, następnie "i" wynik pośredni z innym filtrem daty.

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

Próbowałem Twojego rozwiązania, kompiluje i działa, ale żadne rekordy nie są zwracane. Czy są jakieś specjalne "rzeczy", które muszę zrobić dla porównań typu "DateTime", o których wiecie? – Quoter

+2

Wygląda na to, że istnieją różne wyliczenia dla każdego typu danych filtru, który robisz. A na razie jest to 'TableQuery.GenerateFilterConditionForDate'. I to załatwiło sprawę. Damith, czy możesz to ustawić w swojej odpowiedzi? – Quoter

4

Chciałam tylko dodać jeszcze jedną odpowiedź.

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

Kod przyczyny wyżej zawodzi, ponieważ jest/wartość czasu należy wprowadzić datę w formacie yyyy-MM-ddTHH:mm:ssZ. Więc zapytanie powinno być:

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

Fajnie, ta praca równie dobrze. dzięki! – Quoter

11

Jak mogę ustawić wiele filtrów na Azure Storage Table?

Zastanawiam się, to samo. Napisałem rozszerzenie do klasy TableQuery, która działa dobrze.

Jest to łatwa zmiana, która sprawia, że ​​zastanawiam się, czy mamy zamiar przeprowadzić niepoprawne kwerendy z wieloma filtrami.

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

Jeśli dodajesz wiele filtrów 'Or', to' FilterString' będzie wyglądać jak '(((() lub (Foo eq '1')) lub (Foo eq '2')) lub (Foo eq '3')' . Jeśli 'FilterString' jest pusty, dodaj sam filtr: '@this.FilterString = @ this.FilterString == null? filter: TableQuery.CombineFilters (@ this.FilterString, TableOperators.Or, filter); '. –

7

Używam Windows Azure Storage 7.0.0 i można używać LINQ kwerendy, dzięki czemu nie trzeba już łączyć filtry:

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

Oto wygenerowane zapytanie:

((PartitionKey eq 'partition1') oraz (Datownik datetime'2016-01-31T11: 00: 00Z ')) oraz (Datownik datetime'2016-02-01T11: 00: 00Z')

Można zauważyć, że:

  • Filtry zostały połączone.
  • Daty zostały przekształcone na UTC.