I'm using projection of query results to a custom type, which isn't a part of 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
to be sorted in descending order. Hence, I've tried to add sorting for AvailableVersions
in 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();
With sorting, execution of the query throws an System.Data.EntityCommandCompilationException
with System.InvalidCastException
as inner exception:
Unable to cast object of type 'System.Data.Entity.Core.Query.InternalTrees.SortOp' to type 'System.Data.Entity.Core.Query.InternalTrees.ProjectOp'
Without .OrderByDescending(v => v.Id)
everything works fine.
Is this yet another feature, that isn't supported in Entity Framework, or I've missed something?
P.S. I know, that I can sort items later at client side, but I'm wondering about sorting at the server side.
This is a bug in EF. I was able to repro this on both EF5 and EF6. I think you should be able to workaround the bug by filtering records before creating the results i.e.:
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 a feeling that this query could be simplified if you go from the other side of relationship (i.e. from Orders) but it may depend on how the someQueryable
is created.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With