在投影中对嵌套集合进行排序:无法将"SortOp"类型的对象强制转换为"ProjectOp"类型

Den*_*nis 9 c# entity-framework entity-framework-6

我正在使用查询结果投影到自定义类型,它不是实体数据模型的一部分:

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; }
}
Run Code Online (Sandbox Code Playgroud)

我想AvailableVersions按降序排序.因此,我试图AvailableVersions在投影中添加排序:

        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();
Run Code Online (Sandbox Code Playgroud)

随着分选,查询的执行将引发System.Data.EntityCommandCompilationExceptionSystem.InvalidCastException作为内部异常:

无法将类型为"System.Data.Entity.Core.Query.InternalTrees.SortOp"的对象强制转换为"System.Data.Entity.Core.Query.InternalTrees.ProjectOp"

没有.OrderByDescending(v => v.Id)一切正常.
这是另一个功能,实体框架不支持,或者我错过了什么?

PS我知道,我可以稍后在客户端对项目进行排序,但我想知道在服务器端进行排序.

Paw*_*wel 8

这是EF中的一个错误.我能够在EF5和EF6上重现这一点.我认为你应该能够在创建结果之前通过过滤记录来解决这个问题,即:

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();
Run Code Online (Sandbox Code Playgroud)

我也有一种感觉,如果你从关系的另一边(即从Orders)开始,这个查询可以简化,但它可能取决于如何someQueryable创建.