Skip to content
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

Sorting a dataset by a LocalDate property using OData '$orderby' command fails #232

Closed
GoogleCodeExporter opened this issue Mar 15, 2015 · 6 comments

Comments

@GoogleCodeExporter
Copy link

What steps will reproduce the problem?
1. Open attached Test project
2. Run Xunit unit tests
3. Two unit tests performing sorts on String and DateTime data will succeed.
4. One unit test performing sort on LocalDate data will fail with 
Microsoft.Data.OData.ODataException : The $orderby expression must evaluate to 
a single value of primitive type.

What is the expected output? What do you see instead?
Expect all 3 unit tests to succeed and data to be sorted by the specified 
property.  Instead 2 primitive data type tests succeed (string and datetime) 
and LocalDate date type test fails with exception.

What version of the product are you using? On what operating system?
NodaTime - v1.1.0
RavenDB - v2.5.2666
Microsoft.Data.OData - v5.2.0

Running on Windows 8 Enterprise 64 bit in Visual Studio 2012

Please provide any additional information below.

The stack trace of the thrown exception appears to originate in the OData logic:

Result StackTrace:  
at Microsoft.Data.OData.Query.OrderByBinder.ProcessSingleOrderBy(BindingState 
state, OrderByNode thenBy, OrderByQueryToken orderByToken)
   at Microsoft.Data.OData.Query.OrderByBinder.BindOrderBy(BindingState state, CollectionNode collectionFromPath, IEnumerable`1 orderByTokens)
   at Microsoft.Data.OData.Query.ODataUriParser.ParseOrderBy(String orderBy, IEdmModel model, IEdmType elementType, IEdmEntitySet entitySet)
   at Microsoft.Data.OData.Query.ODataUriParser.ParseOrderBy(String orderBy, IEdmModel model, IEdmType elementType)
   at System.Web.Http.OData.Query.OrderByQueryOption.get_OrderByClause()
   at System.Web.Http.OData.Query.OrderByQueryOption.get_OrderByNodes()
   at System.Web.Http.OData.Query.OrderByQueryOption.ApplyToCore(IQueryable query)
   at System.Web.Http.OData.Query.OrderByQueryOption.ApplyTo(IQueryable query)
   at System.Web.Http.OData.Query.ODataQueryOptions.ApplyTo(IQueryable query, ODataQuerySettings querySettings)
   at System.Web.Http.OData.Query.ODataQueryOptions`1.ApplyTo(IQueryable query, ODataQuerySettings querySettings)
   at System.Web.Http.OData.Query.ODataQueryOptions.ApplyTo(IQueryable query)
   at System.Web.Http.OData.Query.ODataQueryOptions`1.ApplyTo(IQueryable query)
   at Raven.Client.NodaTime.Tests.TestWebAPIController.Get(ODataQueryOptions`1 queryOptions) in c:\....\TestWebAPIController.cs:line 17
   at Raven.Client.NodaTime.Tests.WebAPIODataTests.SortPropertyViaOdata(String sortPropertyName) in c:\....\WebAPIODataTests.cs:line 64
   at Raven.Client.NodaTime.Tests.WebAPIODataTests.Can_Sort_LocalDate_Via_Odata() in c:\....\WebAPIODataTests.cs:line 20

Original issue reported on code.google.com by have...@gmail.com on 27 Jul 2013 at 4:51

Attachments:

@GoogleCodeExporter
Copy link
Author

This is the wrong issue tracker.  Noda Time doesn't have any direct support for 
RavenDB.  Please use the issue tracker at 
https://github.com/mj1856/RavenDB-NodaTime

Also, please use the `RavenDB.Client.NodaTime` nuget package in your test.

Original comment by mj1856 on 27 Jul 2013 at 5:09

@GoogleCodeExporter
Copy link
Author

Actually, don't bother.  It's not a Raven *or* Noda issue.  It is strictly an 
Microsoft OData / EDM thing.

Microsoft.Data.OData.ODataException : The $orderby expression must evaluate   
to a single value of primitive type. 

You will have to find a way to register Noda Time types such that they are 
registered under Microsoft.Data.Edm.IEdmType with TypeKind = 
EdmTypeKind.Primitive.  I don't even know if that is possible or not.

You would have this issue trying to use OData with ANY third-party library, 
regardless of the backing datastore.  You might want to explore building an 
OData add on for Noda Time, but it could be a lot of work.  You need to get 
very familiar with the Microsoft.Data.Edm and Microsoft.Data.Odata libraries.

Original comment by mj1856 on 27 Jul 2013 at 5:28

@GoogleCodeExporter
Copy link
Author

Marking as Invalid as it's not really a Noda Time issue.

Original comment by jonathan.skeet on 30 Jul 2013 at 1:19

  • Changed state: Invalid

@mikhey
Copy link

mikhey commented Jan 16, 2022

I realize that I may be revising a long dead ticket here 🧟‍♂️, but figured I'd document/share some of my recent experiences here as my searches often bringing me back here.

I was able to successfully able to persist NodaTime types RavenDB using Raven.Client.NodaTime and return NodaTime types in JSON using NodaTime Serialization for OData. However, I haven't figured out a way to utilize filtering just yet.

This is what I've done to register Noda Types in oData's model builder:

var builder = new ODataConventionModelBuilder();

builder.AddEnumType(typeof(NodaTime.IsoDayOfWeek));
builder.AddComplexType(typeof(NodaTime.Instant));
builder.AddComplexType(typeof(Nullable<NodaTime.Instant>));
builder.AddComplexType(typeof(NodaTime.Interval));
builder.AddComplexType(typeof(NodaTime.Duration));
builder.AddComplexType(typeof(NodaTime.DateTimeZone));
builder.AddComplexType(typeof(NodaTime.AnnualDate));  
builder.AddComplexType(typeof(NodaTime.ZonedDateTime));
builder.AddComplexType(typeof(NodaTime.OffsetDate));
builder.AddComplexType(typeof(NodaTime.OffsetTime));
builder.AddComplexType(typeof(NodaTime.OffsetDateTime));
builder.AddComplexType(typeof(NodaTime.LocalDate));
builder.AddComplexType(typeof(NodaTime.LocalTime));
builder.AddComplexType(typeof(NodaTime.LocalDateTime));

At this point, I'm going to test projecting the queryable results from NodaTime tyes into System.DateOffset to determine if I can use that for filtering instead.

Hopefully this may help anyone else who may have found themselves in a similar situation.

That said, I'm considering digging a little deeper into OData to see if there is a way that NodaTime types can be registered in the model along with the capability to filter on >, < (& more) operators. Maybe a NodaTime.Edm package or something.

@sniperwolfpk5
Copy link

@mikhey can you tell me how you used NodaTime Serializer for OData. How did you set dependency injection? Did you created a custom serializer for OData. Please help me

@mikhey
Copy link

mikhey commented May 10, 2022

@sniperwolfpk5 Off hand I don't recall, when I get back to my office, I open up the project and get the details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants