Skip to content

New Features in Linq to Querystring v0.6

June 12, 2013

Linq to Querystring v0.6 has just gone live on to Nuget, and contains a whole bunch of new features. This has been the biggest update so far, and brings together some vital components& bug fixes, as well as some cool new bits.

Take a look at the summary below, and also try stuff out on the updated demo site. As usual you can also find the source on our github page, and download the latest version via NuGet!

Server side page limit

You can now specify a hard page-size limit for OData queries so clients can’t just hammer your server repeatedly. You can do this via the Web API action filter:

[LinqToQueryable(maxPageSize=1000)]

Or directly via the LinqToQuerystring extension method

dbcontext.Users.LinqToQuerystring("$skip=3000", maxPageSize: 1000);

Clients can still request a page size smaller than this; the max will only kick in if their specified page size is greater, or omitted.

We’re also planning to add more control over queries and allowed operators, similar to those provided by the WebApi OData offering.

(More) complete list of data types

In addition to the existing String/Int/Date/Complex properties, we’ve now got around to testing and ensuring that the following data types will also work as expected:

Type Example
Long
30000000000L
Single
123.456f
Double
12345678.234234
Byte
0..255 or 0x00 to 0xFF
Guid
guid'12345678-aaaa-bbbb-cccc-ddddeeeeffff'

You can check out the OData specification for more details on the format of each data type.

Please note that specifying a byte in hex form may not be part of the v3 specification… if anyone can find me the relevant section of the v3 spec concerning data types then please let me know in the comments as I haven’t yet.

Any/All on enumerable properties

Any & all are defined in the OData v3 spec, and now work with Linq to Querystring too:

$filter=Tags/any(tag: tag eq 'Important') // Find any records tagged as important
$filter=Orders/all(order: order.Size > 10000) // Find customers that have placed only large orders

As long as your Linq Provider supports the query, you can use these will loosely typed data too by marking a property as dynamic using [ ]:

$filter=[Tags]/any(tag: tag eq 'Important')
$filter=[Orders]/all(order: order.[Size] > 10000)

Numeric aggregates

With v0.6, you can now also use the following aggregate functions against Enumerable properties in your queries:

Function Example
Count()
$filter=Tags/count() gt 1
Sum()
$filter=Value/sum() ge 100000
Average()
$filter=Result/average() lt 50
Max()
$filter=Grade/max() eq 'A'
Min()
$filter=Grade/min() eq 'F'

Min and Max will work with data types that are comparable according to support by the underlying Linq Provider. All the others will only work with int/long/single/double. None of the above functions take any sub-queries or parameters at this time.

Please note that these aggregates are not in the OData specification as v3 (although they do have Linq equivalents) and the format may change if and when these are added.

Bug fixes

We’ve also addressed some stuff that has come out of the woodwork while tinkering, particularly when using Linq to Querystring against loosely typed data in MongoDB:

  • If either side of a comparison is of type Object, such as when using the dynamic keyword, the framework will attempt to convert this property to the type of it’s opposite counterpart.
  • When an operand evaluates to a boolean, and it’s counterpart is a constant then this will be removed to address issues with linq providers such as Mongo and Entity Framework
  • Constant expressions can now feature on either side of a comparison
  • Added an extensibility point to allow conversion of certain types when creating enumerable expressions, to facilitate situations where an enumerable type is not generic.
  • Added the ability to specify an extra cast when dealing with types that a linq provider does not directly support, but can be boxed to another type such as single->double, byte->int.

We need your feedback

I hope you’ll find some of these features useful… we’ll be covering some more specifics relating to Mongo DB very soon too, so watch this space!

As always please comment or let us know if you like Linq to Querystring and are using it for your project, or if you would like to see any particular features added.

Pete

From → OData, Web API

2 Comments
  1. Dmitry permalink

    I really like this project because it allows more granular and customizable OData support than the common solutions.

    I did find a problem right away. The aggregate operations do not seem to work for arrays. It looks like the following code on GitHub in the aggregate nodes does not cover them.

    if (typeof(IEnumerable).IsAssignableFrom(property.Type) && property.Type.GetGenericArguments().Any())
    {
    underlyingType = property.Type.GetGenericArguments()[0];
    }

    It can be changed to:

    if (typeof(IEnumerable).IsAssignableFrom(property.Type))
    {
    underlyingType =property.Type.GetGenericArguments().Any() ? property.Type.GetGenericArguments()[0] : property.Type.GetElementType();
    }

    Thanks,
    Dmitry

    • roysvork permalink

      Thanks for your support! I am hoping to have some time to spend on the project next week after a busy period just now, so I will try to address this. Alternatively if you wish to log an issue on github and/or submit a pull request that would be good too 🙂

      Pete

Leave a comment