Sorting a nested collection into projection: it is not possible to cast an object of type SortOp to enter "ProjectOp"

I use the projection of the query results on a custom type that is not part of the entity data model:

public sealed class AlgoVersionCacheItem : NotificationObject { public int OrderId { get; set; } public string OrderTitle { get; set; } public int? CurrentVersion { get; set; } public int CachedVersion { get; set; } public IEnumerable<int> AvailableVersions { get; set; } } 

I want AvailableVersions sort in descending order. Therefore, I tried to add sorting for AvailableVersions in the projection:

  return someQueryable .Select(version => new AlgoVersionCacheItem { OrderId = version.OrderId, OrderTitle = version.Order.Title, CurrentVersion = version.Order.CurrentAlgoVersionId, CachedVersion = version.Id, AvailableVersions = version .Order .AlgoVersions .Where(v => (allowUncommittedVersions || v.Statuses.Any(s => s.AlgoVersionStatusListItemId == ModelConstants.AlgoVersionCommitted_StatusId)) && v.Id != version.Id) .OrderByDescending(v => v.Id) // this line will cause exception .Select(v => v.Id) }) .Where(item => item.AvailableVersions.Any()) .OrderByDescending(item => item.OrderId) .ToArray(); 

When sorting, query execution raises a System.Data.EntityCommandCompilationException with System.InvalidCastException as an internal exception:

Cannot start an object of type 'System.Data.Entity.Core.Query.InternalTrees.SortOp' to enter type 'System.Data.Entity.Core.Query.InternalTrees.ProjectOp'

Without .OrderByDescending(v => v.Id) everything works fine.
Is this another feature that is not supported in the Entity Framework, or am I missing something?

PS I know that I can sort items later on the client side, but I'm interested in sorting on the server side.

+7
c # entity-framework entity-framework-6
source share
1 answer

This is an error in EF. I was able to reproduce this on both EF5 and EF6. I think you should be able to circumvent the error by filtering the entries before creating ie results:

 return someQueryable .Where(version => version.Order.AlgoVersions.Any(v => (allowUncommittedVersions || v.Statuses.Any(s => s.AlgoVersionStatusListItemId == ModelConstants.AlgoVersionCommitted_StatusId)) && v.Id != version.Id)) .Select(version => new AlgoVersionCacheItem { OrderId = version.OrderId, OrderTitle = version.Order.Title, CurrentVersion = version.Order.CurrentAlgoVersionId, CachedVersion = version.Id, AvailableVersions = version .Order .AlgoVersions .Where(v => (allowUncommittedVersions || v.Statuses.Any(s => s.AlgoVersionStatusListItemId == ModelConstants.AlgoVersionCommitted_StatusId)) && v.Id != version.Id) .OrderByDescending(v => v.Id) // this line will cause exception .Select(v => v.Id) }) .OrderByDescending(item => item.OrderId) .ToArray(); 

I also have the feeling that this query can be simplified if you go from the other side of the relationship (i.e. from Orders), but this may depend on how someQueryable is created.

+7
source share

All Articles