Linq TableServiceContext与动态查询

Linq TableServiceContext与动态查询,linq,azure,expression,dataservice,Linq,Azure,Expression,Dataservice,我试图做一些看起来很简单的事情,但当我想让它更有活力时,我遇到了巨大的困难 Expression<Func<TableServiceEntity, bool>> predicate = (e) => e.PartitionKey == "model" && (e.RowKey == "home" || e.RowKey == "shared"); context.CreateQuery<TableServiceEntity>(t

我试图做一些看起来很简单的事情,但当我想让它更有活力时,我遇到了巨大的困难

    Expression<Func<TableServiceEntity, bool>> predicate = (e) => e.PartitionKey == "model" && (e.RowKey == "home" || e.RowKey == "shared");

context.CreateQuery<TableServiceEntity>(tableName).Where(predicate);
Expression谓词=(e)=>e.PartitionKey==“model”&&(e.RowKey==“home”| e.RowKey==“shared”);
CreateQuery(tableName).Where(谓词);
我希望传递一个rowKey数组,而不必硬编码谓词

当我尝试构建表达式树时,我收到一个不受支持的异常,我认为它不支持作为表达式树的一部分进行调用

有人知道如何准确地构建和表达式树作为谓词以避免不受支持的异常吗


advance感谢您,因此,您可以使用以下内容(取自示例)动态构建查询:

表达式搜索=null;
foreach(标签中的var标签)
{
var id=tag.Trim().ToLowerInvariant();
if(String.IsNullOrEmpty(id))
{
继续;
}
表达式address=t=>t.PartitionKey==id;
如果(搜索==null)
{
搜索=附录;
}
其他的
{
search=Expression.Lambda(Expression.OrElse(search.Body,address.Body),search.Parameters);
}
}
现在,一旦有了“search”,就可以在Where子句中将其作为谓词传递

然而,我想说服你不要这样做。我正在回答您的问题,但告诉您在表存储中执行多个“|”或子句是个坏主意。原因是,至少在今天,这些查询无法优化,它们会导致全表扫描。如果数据量不小,性能将非常糟糕。此外,如果您像这样动态地构建谓词,您将面临超出URL限制的风险(请记住这一点)

PhluffyFotos中的这段代码说明了如何使用它,但实际上这是一种糟糕的做法(我知道,是我写的)。它确实应该进行优化,以并行地分别运行每个OR子句。这才是你真正应该做的。AND子句是可以的,但是OR子句应该并行化(使用PLINQ或TPL),您应该聚合结果。速度会快得多


HTH.

这是我的解决方案,请阅读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);
var parameter=Expression.parameter(typeof(TableServiceEntity),“e”);
var getPartitionKey=typeof(TableServiceEntity).GetProperty(“PartitionKey”).GetGetMethod();
var getRowKey=typeof(TableServiceEntity).GetProperty(“RowKey”).getMethod();
var getPartition=Expression.Property(参数,getPartitionKey);
var getRow=Expression.Property(参数,getRowKey);
var constPartition=Expression.Constant(“model”,typeof(string));
var constRow1=表达式.常量(“home”,typeof(string));
var constRow2=表达式.常量(“共享”,类型(字符串));
var equalPartition=表达式.Equal(getPartition,constPartition);
var equalRow1=表达式.Equal(getRow,constRow1);
var equalRow2=表达式.Equal(getRow,constRow2);
var和=表达式AndAlso(等分,表达式OrElse(等分1,等分2));
返回表达式.Lambda(和,参数);

我相信从我所阅读的文档来看,HTH关于进行完整表扫描的此类查询的说法是不正确的。Azure将执行分区扫描而不是表扫描,这在性能上是一个很大的差异。

您好,谢谢您的输入,您对Or子句not OPTIMATIZED的评论对我来说是无价的!为此,我将查看PLINQ,并更改我的实现以正确执行它。我设法用另一种方式来表达,我把它贴在下面。再次感谢你非常宝贵的LOL。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);