tableserviceContext和动态查询
-
12-11-2019 - |
题
我试图做一些看起来很简单的事情,但是当我想做更多的动态时,我遇到了大规模的困难。
Expression<Func<TableServiceEntity, bool>> predicate = (e) => e.PartitionKey == "model" && (e.RowKey == "home" || e.RowKey == "shared");
context.CreateQuery<TableServiceEntity>(tableName).Where(predicate);
.
我想传递一系列的rowkey,而不是必须硬代码谓词。
当我尝试构建表达式树时,我会收到不支持的异常,我认为它不支持作为表达式树的一部分调用。
有人知道如何构建和表达树完全作为谓词以避免不支持的异常?
谢谢你提前
解决方案
所以,您可以通过使用这样的内容来动态构建查询(从 phluffyfotos 样本):
Expression<Func<PhotoTagRow, bool>> search = null;
foreach (var tag in tags)
{
var id = tag.Trim().ToLowerInvariant();
if (String.IsNullOrEmpty(id))
{
continue;
}
Expression<Func<PhotoTagRow, bool>> addendum = t => t.PartitionKey == id;
if (search == null)
{
search = addendum;
}
else
{
search = Expression.Lambda<Func<PhotoTagRow, bool>>(Expression.OrElse(search.Body, addendum.Body), search.Parameters);
}
}
.
现在,一旦你有'搜索',你就可以通过它作为Where子句中的谓词。
然而,我想说服你不要这样做。我在回答你的问题,但是告诉你,做一个多个'|'是一个坏主意或在表存储中的子句。原因是,今天至少,这些查询无法优化,它们会导致完整的表扫描。任何非琐碎量的数据都将令人惊叹。此外,如果您像素动态构建谓词,那么就会冒出吹嘘URL限制的风险(请记住这一点)。
PhluffyFotos中的这个代码展示了如何,但实际上是一个糟糕的练习(我知道,我写了它)。它真的应该优化,以便并行分开运行每个或子句。这就是你真的应该做的。和条款是可以的,但或者条款应该是并行化的(使用PLINQ或TPL),你应该汇总结果。它会更快。
hth。
其他提示
我相信关于做完整表扫描的这种查询的HTH从我读取的文档中不正确。Azure将执行分区扫描而不是表扫描,这是性能的大差异。
这是我的解决方案,请从Hth读取的答案,谁指出这不是最好的做法。
var parameter = Expression.Parameter(typeof(TableServiceEntity), "e");
var getPartitionKey = typeof(TableServiceEntity).GetProperty("PartitionKey").GetGetMethod();
var getRowKey = typeof(TableServiceEntity).GetProperty("RowKey").GetGetMethod();
var getPartition = Expression.Property(parameter, getPartitionKey);
var getRow = Expression.Property(parameter, getRowKey);
var constPartition = Expression.Constant("model", typeof(string));
var constRow1 = Expression.Constant("home", typeof(string));
var constRow2 = Expression.Constant("shared", typeof(string));
var equalPartition = Expression.Equal(getPartition, constPartition);
var equalRow1 = Expression.Equal(getRow, constRow1);
var equalRow2 = Expression.Equal(getRow, constRow2);
var and = Expression.AndAlso(equalPartition, Expression.OrElse(equalRow1, equalRow2));
return Expression.Lambda<Func<TableServiceEntity, bool>>(and, parameter);
. 不隶属于 StackOverflow