我试图做一些看起来很简单的事情,但是当我想做更多的动态时,我遇到了大规模的困难。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top