Reputation: 3779
I am getting (a little bit to) deep into automapping with the fluent interface of NHibernate. Very nice thing, but I ran into a little problem with DateTimes. I need to change the data format to timestamp, otherwise NHibernate truncates milliseconds.
I found several sources of information, the best one was: AutoMapping Info 1 where he is changing the column name and type of a property. The problem is, there was a change in the fluent automappings, according to this document.
Now I cant figure out how to get the automapping to "change the type". I tried the following code, but I am stuck. Again, what I want to do is simply tell the automapper to:
Use Timestamps for DateTime to prevent the truncation of milliseconds when using automapping.
Anyone got an idea? Code so far:
public class DateTimeToTimestamp : IClassConvention
{
public bool Accept(IClassMap target)
{
return target.GetType() == typeof(DateTime);
}
public void Apply(IClassMap target)
{
throw new NotImplementedException();
}
}
Ok, thanks a lot for the answer... Its enough comfort for me that way. If I really have 3 classes which need this precision, I can deal with writing it three times. Especially because the mapping of all other properties works still perfectly, and the following code only alternates the one property I want to... Very nice!
If anybody knows a more generic approach, feel free to add it, but for now, I am happy!
Code for my case was:
public class DateTimeToTimestamp : IAutoMappingOverride<CustomTime>
{
public void Override(AutoMap<CustomTime> mapping)
{
mapping.Map(x => x.ScanDate).CustomTypeIs("timestamp");
}
}
Upvotes: 4
Views: 7046
Reputation: 38390
To expand on Derek's answer, in order to do it on a more general level, you would use an automapping convention:
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>();
}
}
Upvotes: 11
Reputation: 3763
Danie's answer is the one to use, though there is a small change that needs to be made to the Apply() method for it to work: CustomSqlType("timestamp") -> CustomType("Timestamp"). I verified this as i have just implemented the solution in my own project.
Note: I tried to submit an edit to Daniel's answer above, but couldn't because the change was too small so here is the corrected code:
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");
}
}
In addition, seeing as i am writing a new post, here is a stripped-down example of how you create a session factory with Fluent NHibernate that uses the convention, for the benefit of others who may not know:
var factory = Fluently.Configure()
.Mappings(m => m.FluentMappings.Conventions.Add(new TimestampConvention()))
.BuildSessionFactory();
Kudos to this post for making me aware of this, as i saw a lot of other posts on the net with this same problem.
Upvotes: 2
Reputation: 11391
You can override a specific class. Not sure how to do this on a more general level though.
public class AlbumMappingOverride : IAutoMappingOverride<Album>
{
public void Override(AutoMap<Album> mapping)
{
mapping.Map(x => x.Created).CustomSqlTypeIs("timestamp");
}
}
Upvotes: 2