9

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

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; }
}

我想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();

通过排序,查询的执行会抛出一个System.Data.EntityCommandCompilationExceptionwith System.InvalidCastExceptionas 内部异常:

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

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

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

4

2 回答 2

9

这是 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();

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

于 2013-11-05T00:39:59.463 回答
0

在我的情况下,Linq 查询选择了一个新的匿名构造,其中一个属性设置为集合ToList()扩展方法。我删除了嵌入式执行,错误消失了,系统仍然运行良好。

于 2018-11-14T17:42:38.150 回答