The issue is fully described here
http://stackoverflow.com/questions/2304849/unit-testing-nhibernate-w-sqlite-and-datetimeoffset-mappings

We are using SQLite in our unit tests, and SQLite doesnot support
DateTimeOffset. As suggested in the blog post I created a custom User
Type that implements the IUserType interface, to use in for the Nh
Mapping in the Inmemory database.

code for the custom user types:
        public class NormalizedDateTimeUserType : IUserType
        {
                private readonly TimeZoneInfo databaseTimeZone = 
TimeZoneInfo.Local;


                public virtual Type ReturnedType
                {
                        get { return typeof(DateTimeOffset); }
                }

                public virtual bool IsMutable
                {
                        get { return false; }
                }

                public virtual object Disassemble(object value)
                {
                        return value;
                }

                public virtual SqlType[] SqlTypes
                {
                        get { return new[] { new SqlType(DbType.DateTime) }; }
                }

                public virtual bool Equals(object x, object y)
                {
                        return object.Equals(x, y);
                }

                public virtual int GetHashCode(object x)
                {
                        return x.GetHashCode();
                }

                public virtual object NullSafeGet(IDataReader dr, string[] 
names,
object owner)
                {
                        object r = dr[names[0]];
                        if (r == DBNull.Value)
                        {
                                return null;
                        }

                        DateTime storedTime = (DateTime)r;
                        return new DateTimeOffset(storedTime,
this.databaseTimeZone.BaseUtcOffset);
                }

                public virtual void NullSafeSet(IDbCommand cmd, object value, 
int
index)
                {
                        if (value == null)
                        {
                                NHibernateUtil.DateTime.NullSafeSet(cmd, null, 
index);
                        }
                        else
                        {
                                IDataParameter parameter = 
(IDataParameter)cmd.Parameters[index];
                                try
                                {
                                        DateTimeOffset dateTimeOffset = 
(DateTimeOffset)value;
                                        DateTime paramVal =
dateTimeOffset.ToOffset(this.databaseTimeZone.BaseUtcOffset).DateTime;

                                        parameter.Value = paramVal;
                                }
                                catch (Exception e)
                                {
                                        parameter.Value = DateTime.MinValue;
                                }
                        }
                }

                public virtual object DeepCopy(object value)
                {
                        return value;
                }

                public virtual object Replace(object original, object target, 
object
owner)
                {
                        return original;
                }

                public virtual object Assemble(object cached, object owner)
                {
                        return cached;
                }
        }

        public class NormalizedNullabeDateTimeUserType :
NormalizedDateTimeUserType
        {
                public override Type ReturnedType
                {
                        get { return typeof(DateTimeOffset?); }
                }
        }

        public class NormalizedDateTimeUserTypeConvention :
UserTypeConvention<NormalizedDateTimeUserType>
        {

        }

        public class NormalizedNullableDateTimeUserTypeConvention :
UserTypeConvention<NormalizedNullabeDateTimeUserType>
        {

        }

Mapping code:
Fluently.Configure()
                                .Database(_configuration.DbConfiguration)
                                .Mappings(m =>
                                {
                                        m.FluentMappings
                                                
.Add<DemographicsVerificationMap>()
                                        m.AutoMappings
                                                .Add(new 
AutoPersistenceModel().Instance);
                                        m.FluentMappings.Conventions.Add(new
NormalizedDateTimeUserTypeConvention(), new
NormalizedNullableDateTimeUserTypeConvention());
                                })
                                .ExposeConfiguration(
                                        x => 
x.SetProperty("current_session_context_class",
_configuration.SessionLifecyletype.ToNhibernateString()))
                                .BuildConfiguration();

Even with this, I still get this exception when I rebuild the schema
using:
schemaExport.Execute(false, true, false, connection, null);

Exception:
System.ArgumentException : Dialect does not support
DbType.DateTimeOffset
Parameter name: typecode
at NHibernate.Dialect.Dialect.GetTypeName(SqlType sqlType)
at NHibernate.Mapping.Table.SqlCreateString(Dialect dialect, IMapping
p, String defaultCatalog, String defaultSchema)
at NHibernate.Cfg.Configuration.GenerateSchemaCreationScript(Dialect
dialect)
at NHibernate.Tool.hbm2ddl.SchemaExport.Initialize()
at NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Action`1 scriptAction,
Boolean export, Boolean justDrop, IDbConnection connection, TextWriter
exportOutput)
at Mede.Pai.Dal.NhibernateSessionFactoryManager.BuildSchema() in
NhibernateSessionFactoryManager.cs: line 39
at Mede.Pai.IntegrationTest.InMemoryDbTestBase.SetUpBase() in
InMemoryDbTestBase.cs: line 35

My guess is the Conventions are getting registered in the
configuration.

When I explicitly  register the custom type using for individual
DateTimeOffset properties(below) it works as expected, so it doesn't
seem to be a problem with the CustomType but a problem with how the
conventions are registered.
        m.Map(x => x.DateAdded).CustomType(typeof
(NormalizedDateTimeUserType));

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to