2017-10-18 42 views
0

J'ai une table Foo:Comment exécuter l'agrégat NHibernate sur un TimeSpan?

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

C'est mis en correspondance avec une classe:

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

Et dans le NHibernate ClassMap<Foo>:

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

Tout bien jusqu'à présent. Maintenant, je veux écrire une requête pour obtenir un agrégat de TimeSpent par utilisateur. Dans un monde idéal, il serait:

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

Mais il n'y a pas de support natif pour sommer TimeSpan valeurs, donc au lieu pourrait-on dire:

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

Mais bien sûr, NHibernate ne sait pas ce que cela TotalMilliseconds la propriété est, parce que c'est purement une construction C#.

Quelle est la bonne façon d'agréger les valeurs TimeSpan dans NHibernate?

Répondre

0

ELABOREE une solution possible moi-même:

Ajouter un champ long à la classe:

public long TimeSpentTicks {get; set;} 

Ajoutez le mappage:

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

Et faire l'ensemble comme ceci:

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