我正在使用查询结果投影到自定义类型,而自定义类型不是实体数据模型的一部分:
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.EntityCommandCompilationException
System.InvalidCastException
作为内部异常:
无法投射类型的对象 键入'System.Data.Entity.Core.Query.InternalTrees.SortOp' 'System.Data.Entity.Core.Query.InternalTrees.ProjectOp'
没有.OrderByDescending(v => v.Id)
一切正常
这是另一个功能,实体框架不支持,或者我错过了什么?
P.S。我知道,我可以稍后在客户端对项目进行排序,但我想知道在服务器端进行排序。
答案 0 :(得分: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();
我还有一种感觉,如果你从关系的另一端(即从Orders)开始,这个查询可以简化,但它可能取决于someQueryable
的创建方式。
答案 1 :(得分:0)
在我的情况下,Linq查询正在选择一个新的匿名构造,该构造将一个属性设置为集合ToList()
扩展方法。我删除了嵌入式执行,错误消失了,系统仍然运行正常。