如何 运行 NHibernate 在 TimeSpan 上聚合?

How to run NHibernate aggregate on a TimeSpan?

我有一个 table Foo:

create table Foo(
  FooId uniqueidentifier not null,
  UserId uniqueidentifier not null,
  TimeSpent bigint not null)

这映射到 class:

public class Foo
{
  public Guid FooId {get; set;}
  public Guid UserId {get; set;}
  public TimeSpan TimeSpent {get; set;}
}

并且在 NHibernate 中 ClassMap<Foo>:

Id(x => x.FooId).Not.Nullable().GeneratedBy.GuidComb();
Map(x => x.UserId).Not.Nullable();
Map(x => x.TimeSpent).Not.Nullable();

到目前为止一切都很好。现在我想编写一个查询来获取每个用户 TimeSpent 的总和。在理想的世界中,它将是:

return Session.Query<Foo>()
  .GroupBy(f => f.UserId)
  .Select(g => new { UserId = g.Key, TotalTimeSpent = g.Sum(f => f.TimeSpent) });

但是本机不支持求和 TimeSpan 值,因此我们可以说:

TotalTimeSpent = TimeSpan.FromMilliseconds(g.Sum(f => f.TimeSpent.TotalMilliseconds))

当然,NHibernate 不知道这个 TotalMilliseconds 属性 是什么,因为那纯粹是一个 C# 构造。

在 NHibernate 中聚合 TimeSpan 值的正确方法是什么?

自己想出了一个可能的解决方案:

long 字段添加到 class:

public long TimeSpentTicks {get; set;}

添加映射:

Map(x => x.TimeSpentTicks).Column("TimeSpent").ReadOnly();

然后像这样进行聚合:

var result = Session.Query<Foo>()
 .GroupBy(f => f.UserId)
 .Select(g => new { UserId = g.Key, TotalTicks = g.Sum(f => f.TimeSpentTicks) })
 .ToList() // so we can convert to TimeSpan in managed code
 .Select(x => new { x.UserId, TotalTime = TimeSpan.FromTicks(x.TotalTicks) });