2009-05-21 8 views
4

Je suis en train d'approfondir (un peu à) dans l'auto-apprentissage avec l'interface fluide de NHibernate. Très bonne chose, mais j'ai rencontré un petit problème avec DateTimes. J'ai besoin de changer le format de données en horodatage, sinon NHibernate tronque les millisecondes.Automatisation NHibernate: Alter DateTime à Timestamp

J'ai trouvé plusieurs sources d'information, la meilleure était: AutoMapping Info 1 où il change le nom de la colonne et le type d'une propriété. Le problème est, il y avait un changement dans les automappings fluent, selon this document.

Maintenant, je ne sais pas comment obtenir l'automapping pour "changer le type". J'ai essayé le code suivant, mais je suis bloqué. Encore une fois, ce que je veux faire est simplement dire l'automapper à:

Utilisez des horodatages pour DateTime pour éviter la troncature de millisecondes lors de l'utilisation de l'automapping.

Quelqu'un a eu une idée? Code à ce jour:

public class DateTimeToTimestamp : IClassConvention 
{ 
    public bool Accept(IClassMap target) 
    { 
     return target.GetType() == typeof(DateTime); 
    } 

    public void Apply(IClassMap target) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Ok, merci beaucoup pour la réponse ... Son assez de confort pour moi de cette façon. Si j'ai vraiment 3 classes qui ont besoin de cette précision, je peux m'occuper de l'écrire trois fois. D'autant plus que la cartographie de toutes les autres propriétés fonctionne encore parfaitement, et le code suivant ne fait qu'alterner la propriété que je veux ... Très sympa!

Si quelqu'un connaît une approche plus générique, n'hésitez pas à l'ajouter, mais pour l'instant, je suis heureux!

Code pour mon cas était:

public class DateTimeToTimestamp : IAutoMappingOverride<CustomTime> 
{ 
    public void Override(AutoMap<CustomTime> mapping) 
    { 
     mapping.Map(x => x.ScanDate).CustomTypeIs("timestamp"); 
    } 
} 

Répondre

2

Vous pouvez remplacer une classe spécifique. Je ne sais pas comment faire cela à un niveau plus général cependant.

public class AlbumMappingOverride : IAutoMappingOverride<Album> 
{ 
    public void Override(AutoMap<Album> mapping) 
    { 
     mapping.Map(x => x.Created).CustomSqlTypeIs("timestamp"); 
    } 
} 
10

Pour développer la réponse de Derek, afin de le faire à un niveau plus général, vous pouvez utiliser une convention de AutoMapping:

public class TimestampTypeConvention : IPropertyConvention, IPropertyConventionAcceptance 
{ 
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) 
    { 
     criteria.Expect(x => x.Type == typeof (DateTime)); 
    } 

    public void Apply(IPropertyInstance instance) 
    { 
     instance.CustomType<TimestampType>(); 
    } 
} 
+0

Merci pour cela, fonctionne un régal! –

+0

Pour étendre la prise en charge de DateTime Nullable et voir comment ajouter des conventions à la configuration, voir [cette réponse] (http://stackoverflow.com/a/30753122/411428).J'aime mieux l'implémentation 'Apply()' dans cette réponse. Notez que les deux réponses fonctionnent également si vous n'utilisez pas l'automapping mais avez des classes de mapping dédiées. – Manfred

+0

Vous devriez vraiment utiliser 'criteria.Expect (x => x.Type == typeof (DateTime) || x.Type == typeof (DateTime?));' –

2

La réponse de Danie est celui à utiliser, bien qu'il y ait un petite modification qui doit être apportée à la méthode Apply() pour qu'elle fonctionne: CustomSqlType ("timestamp") -> CustomType ("Timestamp"). J'ai vérifié cela car je viens de mettre en œuvre la solution dans mon propre projet.

Note: J'ai essayé de soumettre une modification à la réponse de Daniel ci-dessus, mais ne pouvait pas parce que le changement était trop petit alors voici le code corrigé:

public class TimestampTypeConvention : IPropertyConvention, IPropertyConventionAcceptance 
{ 
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) 
    { 
     criteria.Expect(x => x.Type == typeof (DateTime)); 
    } 

    public void Apply(IPropertyInstance instance) 
    { 
     instance.CustomType("Timestamp"); 
    } 
} 

En outre, vu que je suis la rédaction d'un nouveau poste, voici un exemple dépouillée de la façon dont vous créez une usine de session avec Fluent NHibernate qui utilise la convention, au profit des autres qui peuvent ne pas savoir:

var factory = Fluently.Configure() 
     .Mappings(m => m.FluentMappings.Conventions.Add(new TimestampConvention())) 
     .BuildSessionFactory(); 

Kudos à this poste pour m'avoir informé de cela, car j'ai vu beaucoup d'autres messages sur le net avec ce même problème.

+0

Oui, couru dans ce même problème, bon travail monsieur! –

+0

J'ai mis à jour ma réponse pour qu'elle corresponde à la vôtre. Merci Xcalibur! –

+1

Vous devriez vraiment utiliser 'criteria.Expect (x => x.Type == typeof (DateTime) || x.Type == typeof (DateTime?));' –