c# - what - MĂșltiples condiciones de filtro de almacenamiento de tablas de Azure
table storage azure (5)
¿Cómo puedo configurar varios filtros en un almacenamiento de tabla de Azure?
Me preguntaba lo mismo. Escribí una extensión a la clase TableQuery que funciona bien.
Es un cambio fácil que me hace preguntarme si vamos a realizar consultas con varios filtros de manera incorrecta.
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;
}
}
¿Cómo puedo configurar varios filtros en un almacenamiento de tabla de Azure?
Esto es lo que he intentado:
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);
Esto no funciona porque TableQuery.CombineFilters()
solo toma 3 parámetros. Y necesito un parámetro extra para la segunda fecha.
Mi segundo intento:
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);
Esto devuelve 400 bad request
. Pero si elimino el ''datetime'', se ejecuta pero no devuelve resultados, mientras que debería devolver unos 100 registros.
Según this documento de msdn, así es como se deben formatear los tiempos de datos.
Mi resultado debe ser todos los registros que están entre dos fechas.
¿Cómo puedo hacer este trabajo?
Estoy usando Windows Azure Storage 7.0.0 y puedes usar la consulta Linq para que no necesites combinar más los filtros:
// 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();
Aquí está la consulta generada:
((PartitionKey eq ''partition1'') y (Timestamp ge datetime''2016-01-31T11: 00: 00Z '')) y (Timestamp le datetime''2016-02-01T11: 00: 00Z'')
Puedes notar que:
- Los filtros se han combinado.
- Las fechas se han convertido a UTC.
Primero "y" su filtro de partición con uno de los filtros de fecha, luego "y" el resultado intermedio con el otro filtro de fecha.
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);
Solo manejando el caso de una nueva consulta que no tiene un filtro y basado en @LivingOnACloud, preferiría escribirlo de esta manera:
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;
}
Y el resto sigue el mismo control, las cosas pueden ir mejor.
Solo quería añadir una respuesta más.
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);
El código de razón anterior está fallando porque el valor de fecha / hora se debe ingresar en el formato yyyy-MM-ddTHH:mm:ssZ
. Por lo que su consulta debe ser:
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);