2009-10-10 7 views

Répondre

12

Ceci n'est pas spécifique à la fluidité, mais est fondamental pour la cartographie NHibernate. Nous utilisons un intercepteur pour spécifier le type. Il est similaire à l'approche in this blog post qui énumère quelques alternatives. Il existe également un proposed patch (NH-1135) pour gérer nativement UtcDateTime et LocalDateTime. Je vous encourage à voter pour cela.

public class InterceptorBase : EmptyInterceptor 
{ 
    public override bool OnLoad(object entity, object id, object[] state, 
     string[] propertyNames, IType[] types) 
    { 
     ConvertDatabaseDateTimeToUtc(state, types); 
     return true; 
    } 

    private void ConvertDatabaseDateTimeToUtc(object[] state, IList<IType> types) 
    { 
     for (int i = 0; i < types.Count; i++) 
     { 
      if (types[i].ReturnedClass != typeof(DateTime)) 
       continue; 

      DateTime? dateTime = state[i] as DateTime?; 

      if (!dateTime.HasValue) 
       continue; 

      if (dateTime.Value.Kind != DateTimeKind.Unspecified) 
       continue; 

      state[i] = DateTime.SpecifyKind(dateTime.Value, DateTimeKind.Utc); 
     } 
    } 
} 
+0

Je voudrais ajouter à ce que vous devez passer cet objet dans la session NHibernate avant qu'il ne soit utilisé. return factory.OpenSession(); a été remplacé par return factory.OpenSession (new InterceptorBase()); –

+0

Le lien référencé ne fonctionne plus, mais le contenu peut encore être trouvé ici: http://www.milkcarton.com/blog/CategoryView,category,NHibernate.aspx –

+0

Je viens de découvrir que cette approche ne fonctionne pas avec les propriétés DateTime sur un composant :-(. –

35

Au Nhibernate 3.0, en utilisant FluentNHibernate, vous pouvez effectuer les opérations suivantes:

Map(x => x.EntryDate).CustomType<UtcDateTimeType>(); 

Pas besoin d'utiliser des intercepteurs plus.

+2

Une note d'avertissement : 'UtcDateTimeType' force DateTimeKind à Utc.Si vous enregistrez une heure locale, dites 13:30 UTC-3, puis il chargera l'heure comme 13:30 UTC (sans décalage) .Je recommande de convertir manuellement toutes les heures locales à Utc en utilisant 'ToUniversalTime()' ou pour implémenter un "' CustomUtcDateTimeType' "pour gérer automatiquement ce cas –

+0

Notez également que ceci ne s'applique qu'au type SQL" datetime ", pas au type sql" timestamp ". Ouvrage ouvert: https://nhibernate.jira.com/browse/NH-2520 –

+0

Est-il possible d'enregistrer un type personnalisé global pour tous les DateTimes? Si non, comment puis-je tester un appareil, si quelqu'un oublie d'utiliser le type personnalisé? – DELUXEnized

3

En raison de @ réponse de DPeden, et le commentaire par @Ricardo_Stuven semblant avoir une légère confusion, je pensais construire cet exemple:

HAVING:

Map(x => x.EntryDate).CustomType<LocalDateTimeType>(); 

est le même comme ayant: (Ce code est destiné à illustrer, il est pas un exemple à suivre)

Map(x => x._hiddenEntryDate).Column("EntryDate"); 
Ignore(x => x.EntryDate); 

///... 

public class MyEntity 
{ 
    protected virtual DateTime _hiddenEntryDate { get; set; } 
    public DateTime EntryDate 
    { 
     get 
     { 
      return DateTime.SpecifyKind(_hiddenEntryDate, DateTimeKind.Local); 
     } 
     set 
     { 
      _hiddenCreated = DateTime.SpecifyKind(value, DateTimeKind.Local); 
     } 
    } 
} 

a savoir, il appelle jamais .ToLocalTime(), tout ce que vous y passez, ou en sortez, est supposé représenter l'heure locale, il n'est pas forcé d'être, il ne reconnaît pas que le développeur utilisera jamais DateTimeKind correctement.

De même UtcDateTimeType appelle jamais .ToUniversalTime()

Questions connexes