Comment définir plusieurs filtres sur un stockage Azure Table?
C'est ce que j'ai essayé:
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);
Cela ne fonctionne pas car TableQuery.CombineFilters()
ne prend que 3 paramètres. Et j'ai besoin d'un paramètre supplémentaire pour la 2e date.
Mon deuxième essai:
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);
Ceci retourne 400 bad request
. Mais si je supprime le "datetime", il s'exécute mais ne renvoie aucun résultat alors qu'il devrait renvoyer quelques 100 enregistrements.
Selon this doc de msdn, c'est ainsi que les dates/heures doivent être formatées.
Mon résultat devrait être tous les enregistrements qui sont entre deux dates.
Comment puis-je faire ce travail?
D'abord "et" votre filtre de partition avec l'un des filtres de date, puis "et" le résultat intermédiaire avec l'autre filtre de date.
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);
Comment définir plusieurs filtres sur un stockage Azure Table?
Je me demandais la même chose. J'ai écrit une extension de la classe TableQuery qui fonctionne bien.
C'est un changement facile qui me fait me demander si nous interrogeons de manière incorrecte avec plusieurs filtres.
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;
}
}
J'utilise Windows Azure Storage 7.0.0 et vous pouvez utiliser la requête Linq pour que vous n'ayez plus besoin de combiner les filtres:
// 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();
Voici la requête générée:
(((PartitionKey eq 'partition1') et timestamp ge datetime'2016-01-31T11: 00: 00Z ')) et (timestamp le datetime'2016-02-01T11: 00: 00Z')
Vous pouvez remarquer que:
Je voulais juste ajouter une réponse.
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);
Le code anomalie ci-dessus échoue car la valeur date/heure doit être entrée au format yyyy-MM-ddTHH:mm:ssZ
Donc, votre requête devrait être:
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);
Traitant simplement le cas d'une nouvelle requête qui n'a pas déjà de filtre et basée sur @LivingOnACloud, je préférerais l'écrire de cette façon:
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;
}
Et le reste suit le même contrôle, les choses peuvent aller mieux.