-
Notifications
You must be signed in to change notification settings - Fork 349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OData.Client 8 preview fails to translate navigation query #2984
Comments
@uffelauesen thanks for trying out the perview and thanks for reporting this. Could you try this instead: ctx.People.ByKey("russelwhyte").Select(p => p.BestFriend).GetValue // or GetValueAsync() The problem here is that when you use the where clause against the People entity set, it will always return a collection of Person entities. When you add select and expand query options, those properties will be nested inside the person entities. The OData spec currently provides no way to return only the expanded objects (without having them nested in the parent) through query options. That's why the LINQ expression fails, it doesn't map to any OData URI pattern. Why did it work in 7.x? Well in 7.x, when we had a where clause whose predicate is a match against the key property, we would convert that in key lookup (equivalent to ByKey()), so it would be translated to You can enable the 7.x behaviour by setting the I would recommend using the If you want to return a collection of nested objects using a where clause, I'd suggest the following workaround: // fetch people with expanded navigation property using OData URI People?$expand=BestFriend
var people = ctx.People.Expand('BestFriend').ExecuteAsync();
// perform a local LINQ transform on the result data
var bestFriends = people.Select(p => p.BestFriend); |
@habbes thanks for the detailed explanation. I have tried both options - ByKey() as well as setting KeyComparisonGeneratesFilterQuery to false and can confirm that both works as expected. Maybe the deprecated property should be kept for easy backwards compatible behavior without the need to rewrite each and every query. I do however find the thrown exception to be confusing or unclear of what the actual problem is. Btw are there any reason why DataServiceQuerySingle does not have an overload for ToString returning the coresponding url of the query, like you have for DataServiceQuery? I find the ToString overload very handy during debugging. Thanks again |
@uffelauesen thanks for the feedback about retaining the We could look into improving the error message as well. Lastly, |
Linq navigation fails to translate.
Assemblies affected
OData .Net lib 8 preview 1 and 2
Reproduce steps
Using the trippin reference service the following linq query fails to translate to a request Uri...
Expected result
The query would translate to
https://services.odata.org/TripPinRESTierService/People('russellwhyte')/BestFriend
Actual result
You get an exception:
Error translating Linq expression to URI: Can only specify query options (orderby, where, take, skip) after last navigation.
Unhandled exception. System.NotSupportedException: Can only specify query options (orderby, where, take, skip) after last navigation.
at Microsoft.OData.Client.ResourceBinder.ValidationRules.RequireCanNavigate(Expression e)
at Microsoft.OData.Client.ResourceBinder.IsValidNavigationSource(Expression input, ResourceExpression& sourceExpression)
at Microsoft.OData.Client.ResourceBinder.AnalyzeNavigation(MethodCallExpression mce, DataServiceContext context)
at Microsoft.OData.Client.ResourceBinder.VisitMethodCall(MethodCallExpression mce)
at Microsoft.OData.Client.ALinqExpressionVisitor.Visit(Expression exp)
at Microsoft.OData.Client.DataServiceALinqExpressionVisitor.Visit(Expression exp)
at Microsoft.OData.Client.ALinqExpressionVisitor.VisitExpressionList(ReadOnlyCollection
1 original) at Microsoft.OData.Client.ALinqExpressionVisitor.VisitMethodCall(MethodCallExpression m) at Microsoft.OData.Client.ResourceBinder.VisitMethodCall(MethodCallExpression mce) at Microsoft.OData.Client.ALinqExpressionVisitor.Visit(Expression exp) at Microsoft.OData.Client.DataServiceALinqExpressionVisitor.Visit(Expression exp) at Microsoft.OData.Client.ResourceBinder.Bind(Expression e, DataServiceContext context) at Microsoft.OData.Client.DataServiceQueryProvider.Translate(Expression e) at Microsoft.OData.Client.DataServiceQuery
1.Translate()at Microsoft.OData.Client.DataServiceQuery
1.Execute() at Microsoft.OData.Client.DataServiceQuery
1.GetEnumerator()at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable
1 source, Boolean& found) at System.Linq.Enumerable.Single[TSource](IEnumerable
1 source)at Microsoft.OData.Client.DataServiceQueryProvider.ReturnSingleton[TElement](Expression expression)
at Microsoft.OData.Client.DataServiceQueryProvider.Execute[TResult](Expression expression)
at OData4ClientTest.Program.Main(String[] args) in C:\Users\Z6UFE\Source\Repos\OData4ClientTest\Program.cs:line 17
Additional detail
Rolling back to OData.Client 7.21.2 and everything works again.
The text was updated successfully, but these errors were encountered: