EF orderby / then combined extension method

I want to be able to use the firstby / thenby to sort as follows:

 allOrders().sort(s => s.ProductName, s => s.OrderDate) 

So, using this post as inspiration , I wrote this extension method, which compiles fine:

 public static IQueryable<T> sort<T>(this IQueryable<T> entities, params Expression<Func<T, object>>[] predicates) where T : class { var sorted = entities.OrderBy(predicates[0]); for (int i = 1; i < predicates.Length; i++) sorted = sorted.ThenBy(predicates[i]); return sorted; } 

And I also tried this version of succint, which also compiles:

 public static IQueryable<T> sort<T>(this IQueryable<T> entities, params Expression<Func<T, object>>[] predicates) where T : class { return predicates.Skip(1).Aggregate( entities.OrderBy(predicates[0]), (aggregate, currentPredicate) => aggregate.ThenBy(currentPredicate)); } 

However, if I try to sort by DateTime , I get this exception:

Cannot enter type "System.DateTime" to enter "System.Object". LINQ to Entities only supports EDM listing of primitive or enumerated types.

What am I doing wrong? I am using EF5.

+4
source share
2 answers

When you return a value type (for example, int or DateTime ) from a lambda expression that returns an object , the compiler generates a Box() call to turn the value type into a boxed object.

The Entity Framework expression parser cannot process this field. The only solution is to pass a strongly typed lambda expression that returns the type of the value.

To do this, you may incorrectly use collection initializers:

 public class OrderingCollection<TEntity> : IEnumerable { public void Add<TProperty>(Expression<Func<TEntity, TProperty>>) { ... } } public static IQueryable<T> Sort<T>(this IQueryable<T> entities, OrderingCollection<T> o) where T : class { ... } q = q.Sort(new OrderingCollection { s => s.ProductName, s => s.OrderDate }); 

Collection initializers allow you to use type inference with an arbitrary number of different type parameters.

+6
source

I think your problem is related to Func<T, object> . This means that you are going to return the object no matter what you sort, and EF cannot match this with the database column type.

The OrderBy() function accepts both TSource and TKey , so you will need to specify the type of key for each view that quickly gets out of control (see Tuple<T1,T2,T3,T4,T5,T6,T7,T8> ).

0
source

Source: https://habr.com/ru/post/1441903/


All Articles