我在使用 LINQ 执行 CosmosDb 查询时遇到问题。当我添加 ORDER BY 子句同时删除它时,主要问题出现了,查询运行顺利。添加 ORDER BY 子句使得查询的第二次迭代,当我添加 continuationToken 时,抛出异常。 这是 continuationToken (我删除了该令牌,因为它很长):
[
{
"compositeToken": {
"token":"+RID:~njgzAO5qBgzIGQAAAAAACA...",
"range": {
"min": "",
"max": "05C1E0"
}
},
"orderByItems": [
{
"item": 74.80897
}
],
"rid": "njgzAO5qBgzIGQAAAAAACA==",
"skipCount": 0,
"filter": "true"
}
]
这是来自异常的消息:
响应状态码不表示成功:BadRequest(400);子状态:0;活动ID:5a692073-43db-4050-a856-d3d7cae01503;原因: ({"errors":[{"severity":"Error","location":{"start":245,"end":246},"code":"SC1001","message":"语法错误,',' 附近的语法不正确。"}]} ActivityId:5a692073-43db-4050-a856-d3d7cae01503、Microsoft.Azure.Cosmos.Tracing.TraceData.ClientSideRequestStatisticsTraceDatum、Windows/10.0.22621 cosmos-netstandard-sdk/3.31.4);
下面是我用于 vreatin tyhe IQuerable 的方法:
private async Task<IQueryable<TDatabase>> _GetQuery(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderByExpression, bool disc, TDatabase s, PagedItem pagedItem = null, Expression<Func<T, object>> orderThenByExpressionPaged = null, bool pagedDesc = false)
{
await Task.CompletedTask;
var queryDefinition = container.GetItemLinqQueryable<TDatabase>(continuationToken: pagedItem.ContinuationToken);//, linqSerializerOptions: LinqOptions);
IQueryable<TDatabase> queryable = queryDefinition.Where(a => true);
Expression<Func<TDatabase, bool>> predicateDb = mapper.Map<Expression<Func<TDatabase, bool>>>(predicate);
Expression<Func<TDatabase, object>> orderByExpressionDB = mapper.Map<Expression<Func<TDatabase, object>>>(orderByExpression);
if (predicateDb != null)
{
queryable = queryable.Where<TDatabase>(predicateDb);
}
IOrderedQueryable<TDatabase> OrderBy = null;
if (orderByExpression != null)
{
if (disc)
OrderBy = queryable.OrderByDescending(orderByExpressionDB);
else
OrderBy = queryable.OrderBy(orderByExpressionDB);
queryable = OrderBy;
}
if (orderThenByExpressionPaged != null)
{
Expression<Func<TDatabase, object>> orderByExpressionThenByDB = mapper.Map<Expression<Func<TDatabase, object>>>(orderThenByExpressionPaged);
if (pagedDesc)
OrderBy = OrderBy.ThenByDescending(orderByExpressionThenByDB);
else
OrderBy = OrderBy.ThenBy(orderByExpressionThenByDB);
queryable = OrderBy;
}
return queryable;
}
我尝试删除调试器中的 ContinuationToken,查询运行良好,但返回之前的结果。
GetItemLinqQueryable()
方法用于创建 LINQ 查询,该查询允许从容器中检索数据。 orderByExpression
和 orderThenByExpressionPaged
用于对查询进行排序。
orderByExpression
使用 Expression<Func<TDatabase, object>>
定义,用于按 Age 属性对结果进行排序,PagingItem 对象用于处理分页。在此 ContinuationToken 属性用于存储并从查询的一次迭代传递到查询的下一次迭代。
在您的代码中,您没有使用
allowSynchronousQueryExecution:true
,它允许同步执行查询,不使用它会给出不同的错误。您收到的错误似乎是语法错误,您可以重用我的代码来实现所需的输出。
我只是使用 order by 过滤来展示 ORDER BY 子句在下面的代码中如何工作。
下面是我尝试过的代码
private async Task<IQueryable<TDatabase>> _GetQuery(
Expression<Func<TDatabase, object>> orderByExpression,
bool desc,
PagingItem pagedItem = null,
Expression<Func<TDatabase, object>> orderThenByExpressionPaged = null,
bool pagedDesc = false)
{
await Task.CompletedTask;
var queryDefinition = container.GetItemLinqQueryable<TDatabase>(continuationToken: pagedItem?.ContinuationToken,
allowSynchronousQueryExecution: true
);
IOrderedQueryable<TDatabase> queryable;
if (desc)
queryable = queryDefinition.OrderByDescending(orderByExpression);
else
queryable = queryDefinition.OrderBy(orderByExpression);
if (orderThenByExpressionPaged != null)
{
if (pagedDesc)
queryable = queryable.ThenByDescending(orderThenByExpressionPaged);
else
queryable = queryable.ThenBy(orderThenByExpressionPaged);
}
return queryable;
}
public async Task MainMethod()
{
string orderByPropertyName = "Age";
Expression<Func<TDatabase, object>> orderByExpression = CreateOrderByExpression(orderByPropertyName);
var queryable = await _GetQuery(orderByExpression, true, null);
var results = queryable.ToList();
foreach (var item in results)
{
Console.WriteLine($"Id: {item.GetType().GetProperty("Id")?.GetValue(item)}, Name: {item.GetType().GetProperty("Name")?.GetValue(item)}, Age: {item.GetType().GetProperty("Age")?.GetValue(item)}, Field: {item.GetType().GetProperty("Field")?.GetValue(item)}");
}
}
输出:
Id: 2, Name: Balaji, Age: 25, Field: NON-IT
Id: 1, Name: Pavan, Age: 24, Field: IT
Id: 3, Name: Pavan Balaji, Age: 23, Field: Software