我有一个LINQ调用组,然后将PossessionTime.Tick值作为新的Timespan求和。这之前工作正常,但现在我需要将集合保持为IQueryable而不是List。
PossessionTime = new TimeSpan(x.Sum(p => p.PossessionTime.Ticks))
通过此更改,我现在收到以下错误:
LINQ中仅支持无参数构造函数和初始值设定项 实体。
我已经研究过使用DbFunctions
,但它没有任何可以帮助我不思考的东西。
我唯一的选择是将列表移动到内存中并将时间相加吗?
IQueryable如下:
return stats.GroupBy(x => x.Id).OrderByDescending(x => x.Sum(a => a.Kills))
.Select(x => new WeaponItem
{
PossessionTime = new TimeSpan(x.Sum(p => p.PossessionTime.Ticks))
});
我需要将它保持为IQueryable,因为我在分页中使用它。
答案 0 :(得分:1)
我不认为你能够使用Linq-to-SQL / EF轻松地使用PossionTime.Ticks
使用直接linq。转换为sql操作时,C#DateTime操作非常有限。
如果您的唯一要求是支持分页,您可以在分页操作后进行WeaponItem
投影,并将页面拉入记忆中,从而轻松实现自己:
return stats
.GroupBy(x => x.Id)
.OrderByDescending(x => x.Sum(a => a.Kills))
// paginatation
.Skip(pageNumber * pageSize)
.Take(pageSize)
// pull paged result set into memory to make life easy
.ToList()
// transform into WeaponItem
.Select(x => new WeaponItem
{
PossessionTime = new TimeSpan(x.Sum(p => p.PossessionTime.Ticks))
});
或者,您可以将WeaponItem
类更改为存储PossesionTimeTicks
,然后将PossesionTime
作为计算属性提供。这可能会绕过限制:
public class WeaponItem
{
public long PosseionTimeTicks {get;set;}
public TimeSpan PossesionTime {get{ return new TimeSpan(PosseionTimeticks); }
}
然后我认为您应该能够将查询保持为IQueryable:
return stats
.GroupBy(x => x.Id)
.OrderByDescending(x => x.Sum(a => a.Kills))
.Select(x => new WeaponItem
{
PossessionTimeTicks = x.Sum(p => p.PossessionTime.Ticks)
});
答案 1 :(得分:0)
您可以使用TimeSpan
从HMS创建DBFunctions.CreateTime
,这样您就可以进行数学转换:
return stats.GroupBy(x => x.Id).OrderByDescending(x => x.Sum(a => a.Kills))
.Select(x => new WeaponItem
{
PossessionTime = DBFunctions.CreateTime(0, 0, x.Sum(p => DBFunctions.DiffSeconds(p.PossessionTime, TimeSpan.Zero)))
});
注意:我假设CreateTime
接受秒参数> = 60秒,否则,您需要将总和转换为小时,分钟和秒。