gpt4 book ai didi

c# - $select 和 $expand 中断 ODataQueryOptions——如何修复?

转载 作者:太空狗 更新时间:2023-10-29 17:39:13 24 4
gpt4 key购买 nike

我们将 Microsoft ASP.NET MVC OData WebAPI 用于我们的 Web 服务。由于围绕层次结构 ID 的一些数据架构问题(超出本次对话的范围),我们的一些 GET 操作必须使用 ODataQueryOptions 并手动操作表达式以添加额外的限制。我们这样做(为清楚起见,删除了错误处理代码并调用了内联的其他方法):

public IQueryable<Person> Get(ODataQueryOptions<Person> oDataQueryOptions)
{
IQueryable<Person> result;
IQueryable<Person> dataSet = context.Persons;

var tempQuery = oDataQueryOptions.ApplyTo(dataSet).Cast<Person>();
var modifier = new HierarchyNodeExpressionVisitor(GetDescendantsOfNode, GetAncestorsOfNode);
var expression = modifier.ModifyHierarchyNodeExpression(tempQuery.Expression);

result = context.Persons.Provider.CreateQuery<Person>(expression);

return result;
}

这一段时间以来一直运行良好,但我们一直热切地等待选择和扩展,以便我们可以更好地控制从我们的服务接收的数据。星期一,我们将我们的开发环境更新为 WebApi OData 5.0.0-rc1 并开始选择和扩展工作,但我们不能将它用于这些使用 ODataQueryOptions 的服务。我们只能将它用于我们的其他服务。如果我们使用 $select 和/或 $expand 查询上面的代码,我们会得到以下错误:

"message": "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.",
"type": "System.InvalidOperationException",
"stacktrace": "",
"internalexception":
{
"message": "Unable to cast the type 'System.Web.Http.OData.Query.Expressions.SelectAllAndExpand`1' to type 'OurCompany.Domains.Data.Models.Person'. LINQ to Entities only supports casting EDM primitive or enumeration types.",
"type": "System.NotSupportedException",
"stacktrace": " at System.Data.Objects.ELinq.ExpressionConverter.ValidateAndAdjustCastTypes(TypeUsage toType, TypeUsage fromType, Type toClrType, Type fromClrType) at System.Data.Objects.ELinq.ExpressionConverter.GetCastTargetType(TypeUsage fromType, Type toClrType, Type fromClrType, Boolean preserveCastForDateTime) at System.Data.Objects.ELinq.ExpressionConverter.CreateCastExpression(DbExpression source, Type toClrType, Type fromClrType) at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.CastMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Objects.ELinq.ExpressionConverter.Convert() at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption) at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable.GetEnumerator() at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.IEnumerable.GetEnumerator() at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer, ODataSerializerContext writeContext) at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders) at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.WebHost.HttpControllerHandler.d__10.MoveNext()"
}

我做了一些谷歌搜索并偶然发现了 thisthis ,但都没有帮助。似乎没有人在做我们正在做的事情并尝试使用选择和展开。我们如何解决这个问题?我在这里不知所措......

最佳答案

问题出在这行代码,

var tempQuery = oDataQueryOptions.ApplyTo(dataSet).Cast<Person>();

Cast 一次无效$select$expand应用结果不再是一个人。这将是一个 Wrapper<Person>仅包含客户要求的属性。您可能需要修改您的 HierarchyNodeExpressionVisitor考虑到这一点。

此外,尝试将您的操作更改为此以处理结果可能不是 IQueryable<Person> 的事实。不再。

    public IHttpActionResult Get(ODataQueryOptions<Person> oDataQueryOptions)
{
IQueryable result;
IQueryable<Person> dataSet = context.Persons;

IQueryable tempQuery = oDataQueryOptions.ApplyTo(dataSet);
var modifier = new HierarchyNodeExpressionVisitor(GetDescendantsOfNode, GetAncestorsOfNode);
var expression = modifier.ModifyHierarchyNodeExpression(tempQuery.Expression);

result = context.Persons.Provider.CreateQuery(expression);

return Ok(result, result.GetType());
}

private IHttpActionResult Ok(object content, Type type)
{
Type resultType = typeof(OkNegotiatedContentResult<>).MakeGenericType(type);
return Activator.CreateInstance(resultType, content, this) as IHttpActionResult;
}

关于c# - $select 和 $expand 中断 ODataQueryOptions——如何修复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18879779/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com