$select und $expand Pause ODataQueryOptions — wie zu beheben?
Sind wir mit Microsoft ASP.NET MVC, OData-WebAPI für unsere web-services. Weil einige Daten-Architektur Fragen rund um Hierarchie-ID (die außerhalb des Geltungsbereichs dieses Gespräch), einige unserer GET-Operationen zu verwenden ODataQueryOptions und manuell Bearbeiten Sie den Ausdruck, um zusätzliche Einschränkungen. Wir tun also so (error handling code entfernt und Aufrufe anderer Methoden inline für Klarheit):
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;
}
Dies hat sehr gut funktioniert für einige Zeit, aber wir waren schon gespannt auf wählen Sie und erweitern Sie so, dass wir besser kontrollieren können, welche Daten wir erhalten von unseren Dienstleistungen. Montag haben wir aktualisiert unsere dev-Umgebung zu WebApi OData-5.0.0-rc1 und bekam wählen Sie und erweitern Sie arbeitet, aber wir können es nicht verwenden, gegen diese Dienste mit ODataQueryOptions. Wir können ihn nur gegen unseren anderen Dienstleistungen. Wenn wir die Abfrage der code oben mit $select
- und/oder $expand
erhalten wir folgenden Fehler:
"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()"
}
Habe ich getan einige Googeln und stolperte über diese und diese, aber weder hilfreich waren. Niemand scheint zu sein, tun ganz das, was wir tun, und versuchen zu verwenden, wählen Sie und erweitern Sie. Wie lösen wir das? Ich bin ratlos hier...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem ist in dieser Zeile des Codes,
Der Cast ist ungültig, sobald
$select
und$expand
angewendet werden, das Ergebnis ist nicht mehr eine Person. Es wäre einWrapper<Person>
enthält nur die Eigenschaften, die der Kunde für. Sie müssen möglicherweise ändern Sie IhreHierarchyNodeExpressionVisitor
dies zu berücksichtigen.Versuchen Sie auch, ändern Sie Ihr handeln, um diese zu behandeln, die Tatsache, dass das Ergebnis möglicherweise nicht eine
IQueryable<Person>
mehr.Person
, nicht einWrapper<Person>
. In der Tat, die exception wird nicht geworfen, irgendwo in meiner Methode. Die exception geworfen wird NACH der Methode zurückgegeben wird.HierarchyNodeExpressionVisitor
. Es ist generisch--es handelt nicht nur aufPerson
. DieModifyHierarchyNodeExpression
Methode ist einfach den Aufruf der standard -Visit
Methode. Es ist nicht irgendetwas anderes tun. Wichtiger ist, keiner der anderen Codes in der Besucher wird immer aufgerufen, für diese einfache$filter
. Auf der Basis-Abfrage, die fehlschlägt, mit diesem Fehler (eindeutiger Schlüssel ( = = ), der Besucher ist ein no-op.HierarchyNodeExpressionVisitor
? Nirgends zu finden.