好的,我在ASP.NET MVC 3应用程序中第一次使用Azure表存储。
我有一个表实体,其用户ID为RowKey。我有一个用户ID列表,需要获取具有其中一个用户ID的所有实体。
在传统的SQL中,您可以动态添加到where子句中的简单OR语句:
select * from blah
where userID = '123' or userID = '456' or userID = '789'
但我在Azure SDK中找不到相应的内容。
Azure Table Storage是否可以实现这一目标?
谢谢, 大卫
答案 0 :(得分:1)
好的,有点挖掘我找到了答案。
您可以使用此处的语法构建where过滤器:http://msdn.microsoft.com/en-us/library/windowsazure/ff683669.aspx
因此,对于我的小例子,它最终看起来像这样:
我有一个以逗号分隔的ID字符串发送到此方法
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["TableStorageConnectionString"]);
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("Blah");
string[] split = IDs.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
string filter = null;
for (int i = 0; i < split.Length; i++)
{
filter += " RowKey eq '" + split[i] + "' ";
if (i < split.Length - 1)
filter += " or ";
}
TableQuery<Blah> rangeQuery = new TableQuery<Blah>().Where(filter);
var result = table.ExecuteQuery(rangeQuery);
结果列出了我需要的好东西。
要记住的一件事是你不想在一个非常大的表上使用它,因为我只获得了导致表扫描的RowKey。如果同时使用PartitionKey和RowKey,则效率更高。我的表非常小(最多几百条记录)所以它不应该成为一个问题。
希望这有助于某人。
大卫
答案 1 :(得分:1)
这样你就可以像那样编写过滤器表达式
string[] split = IDs.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
string mainFilter = null;
foreach (var id in split)
{
var filter = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, id);
mainFilter = mainFilter != null ? TableQuery.CombineFilters(mainFilter, TableOperators.And, filter) : filter;
}
var rangeQuery = new TableQuery<Blah>().Where(mainFilter);
var result = table.ExecuteQuery(rangeQuery);
不幸的是Contains
方法不是supported by the Table Service,但您可以编写一个简单的方法来动态构建您的linq查询:
public static class ContainsExtension
{
public static Expression<Func<TEntity, bool>> Contains<TEntity,
TProperty>(this IEnumerable<object> values,
Expression<Func<TEntity, TProperty>> expression)
{
// Get the property name
var propertyName = ((PropertyInfo)((MemberExpression)expression.Body).Member).Name;
// Create the parameter expression
var parameterExpression = Expression.Parameter(typeof (TEntity), "e");
// Init the body
Expression mainBody = Expression.Constant(false);
foreach (var value in values)
{
// Create the equality expression
var equalityExpression = Expression.Equal(
Expression.PropertyOrField(parameterExpression, propertyName),
Expression.Constant(value));
// Add to the main body
mainBody = Expression.OrElse(mainBody, equalityExpression);
}
return Expression.Lambda<Func<TEntity, bool>>(mainBody, parameterExpression);
}
}
这样您就可以轻松构建动态查询:
var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["TableStorageConnectionString"]);
var tableClient = storageAccount.CreateCloudTableClient();
var table = tableClient.GetTableReference("Blah");
var split = IDs.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
// Create a query: in this example I use the DynamicTableEntity class
var query = table.CreateQuery<DynamicTableEntity>()
.Where(split.Contains((DynamicTableEntity d) => d.RowKey));
// Execute the query
var result = query.ToList();