2

I am using System.Linq.Dynamic and have the following simplified structure (model):

Parent -> Children (Collection of type Child)

Child has property SortingOrder

I would like retrieve list of Parents include Children and order by Sorting Order.

I can do that with LINQ / C# code

Parents.OrderBy(x=>x.Children.OrderBy(z=>z.SortingOrder).Select(z=>z.SortingOrder).FirstOrDefault())

It works fine with EF (6.0) but problem is with all dynamic examples using string I cannot find solution to create the same expressions from string. So ultimately it should be sorted like this

Parents.Include("Children").OrderBy("Children.SortingOrder")

Obviously Children as collection does not have SortingOrder and therefore all examples fails.

Please advice, could not find solution for hours. I think solution would be in creating that lambda expression (x=>x.Children.OrderBy(z=>z.SortingOrder).Select(z=>z.SortingOrder).FirstOrDefault()) dynamically but not sure how to do that, or any other help greatly appreciated.

I am sure it's doable as it's working as compiled strongly typed expression.

Examples of code researched:

Community
  • 1
  • 1

1 Answers1

2

There is no general solution. System.Linq.Dynamic is too limited compared to "normal" LINQ - many functions are not supported, doesn't like sub collections and requres you to use one of the supported "aggregate" functions, which are no more and no less than Any, Count, Min, Max, Sum and Average`.

However, your specific case has alternative solution which is supported by Dynamic LINQ.

Let take your sample query as example.

Parents.OrderBy(x => x.Children.OrderBy(z => z.SortingOrder).Select(z => z.SortingOrder).FirstOrDefault())

is equivalent to

Parents.OrderBy(p => p.Children.Min(c => c.SortingOrder))

which with Dynamic LINQ would be like this

Parents.OrderBy("Children.Min(SortingOrder)")
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
  • Thank you! I am using very simplified example.. For instance, instead of SortingOrder (assuming integer) it would be any other types - bool, strings and etc. I could try your suggestion and see what will happen. – user2287478 Feb 19 '16 at 13:07
  • It worked fine on numeric values (possibly on dates) .. I had to convert booleans to 1/0 so it's partially working :) – user2287478 Feb 19 '16 at 15:06
  • There is just no other option with Dynamic LINQ. It should work for every type that has `Enumerable.Min` function overload, i.e. all numeric types and DateTime. For Booleans - the way you did it. For strings - no way, sorry. – Ivan Stoev Feb 19 '16 at 17:04