Skip to content

Commit 7ec6d87

Browse files
NH-3919 - Allow reverting to DateTime.
1 parent e5151ae commit 7ec6d87

File tree

4 files changed

+80
-13
lines changed

4 files changed

+80
-13
lines changed

src/NHibernate.Test/DialectTest/MsSql2008DialectFixture.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
using System.Reflection;
1+
using System;
2+
using System.Reflection;
23
using NHibernate.Cfg;
34
using NHibernate.Dialect;
45
using NHibernate.Engine;
56
using NHibernate.SqlTypes;
67
using NHibernate.Type;
78
using NUnit.Framework;
9+
using Environment = NHibernate.Cfg.Environment;
810

911
namespace NHibernate.Test.DialectTest
1012
{
1113
[TestFixture]
1214
public class MsSql2008DialectFixture
1315
{
1416
[Test]
15-
public void CheckSql2005DateTimeTypes()
17+
public void CheckPreSql2008DateTimeTypes()
1618
{
1719
var cfg = TestConfigurationHelper.GetDefaultConfiguration();
1820
cfg.SetProperty(Environment.Dialect, typeof(MsSql2005Dialect).FullName);
@@ -45,6 +47,24 @@ public void CheckSql2008DateTimeTypes()
4547
#pragma warning restore 618
4648
}
4749

50+
[Test]
51+
public void CheckKeepDateTime()
52+
{
53+
var cfg = TestConfigurationHelper.GetDefaultConfiguration();
54+
cfg.SetProperty(Environment.Dialect, typeof(MsSql2008Dialect).FullName);
55+
cfg.SetProperty(Environment.SqlTypesKeepDateTime, "true");
56+
var mapping = GetMapping(cfg);
57+
AssertSqlType(NHibernateUtil.DateTime, SqlTypeFactory.DateTime, mapping);
58+
AssertSqlType(NHibernateUtil.Timestamp, SqlTypeFactory.DateTime, mapping);
59+
AssertSqlType(NHibernateUtil.TimestampUtc, SqlTypeFactory.DateTime, mapping);
60+
AssertSqlType(NHibernateUtil.DbTimestamp, SqlTypeFactory.DateTime, mapping);
61+
AssertSqlType(NHibernateUtil.LocalDateTime, SqlTypeFactory.DateTime, mapping);
62+
AssertSqlType(NHibernateUtil.UtcDateTime, SqlTypeFactory.DateTime, mapping);
63+
#pragma warning disable 618 // DateTime2 is obsolete
64+
AssertSqlType(NHibernateUtil.DateTime2, SqlTypeFactory.DateTime2, mapping);
65+
#pragma warning restore 618
66+
}
67+
4868
private static readonly FieldInfo _mappingField =
4969
typeof(Configuration).GetField("mapping", BindingFlags.Instance | BindingFlags.NonPublic);
5070

src/NHibernate/Cfg/Environment.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ public static string Version
208208
/// </summary>
209209
public const string OdbcDateTimeScale = "odbc.explicit_datetime_scale";
210210

211+
/// <summary>
212+
/// Disable switching built-in NHibernate date-time types from DbType.DateTime to DbType.DateTime2
213+
/// for dialects supporting datetime2.
214+
/// </summary>
215+
public const string SqlTypesKeepDateTime = "sql_types.keep_datetime";
216+
211217
/// <summary>
212218
/// <para>Oracle has a dual Unicode support model.</para>
213219
/// <para>Either the whole database use an Unicode encoding, and then all string types

src/NHibernate/Dialect/MsSql2008Dialect.cs

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,37 @@
11
using System.Collections.Generic;
22
using System.Data;
3-
using NHibernate.Cfg;
43
using NHibernate.Dialect.Function;
54
using NHibernate.Driver;
65
using NHibernate.SqlTypes;
76
using NHibernate.Type;
87
using NHibernate.Util;
8+
using Environment = NHibernate.Cfg.Environment;
99

1010
namespace NHibernate.Dialect
1111
{
1212
public class MsSql2008Dialect : MsSql2005Dialect
1313
{
14+
/// <summary>
15+
/// Should <see cref="DbType.DateTime" /> be preserved instead of switching it to <see cref="DbType.DateTime2" />?
16+
/// </summary>
17+
/// <value>
18+
/// <see langword="true" /> for preserving <see cref="DbType.DateTime" />, <see langword="false" /> for
19+
/// replacing it with <see cref="DbType.DateTime2" />.
20+
/// </value>
21+
protected bool KeepDateTime { get; private set; }
22+
23+
public override void Configure(IDictionary<string, string> settings)
24+
{
25+
base.Configure(settings);
26+
27+
KeepDateTime = PropertiesHelper.GetBoolean(Environment.SqlTypesKeepDateTime, settings, false);
28+
if (KeepDateTime)
29+
{
30+
// Re-register functions, they depend on this setting.
31+
RegisterFunctions();
32+
}
33+
}
34+
1435
protected override void RegisterDateTimeTypeMappings()
1536
{
1637
base.RegisterDateTimeTypeMappings();
@@ -23,8 +44,15 @@ protected override void RegisterDateTimeTypeMappings()
2344
protected override void RegisterFunctions()
2445
{
2546
base.RegisterFunctions();
26-
RegisterFunction("current_timestamp", new NoArgSQLFunction("sysdatetime", NHibernateUtil.DateTime, true));
27-
RegisterFunction("current_timestamp_offset", new NoArgSQLFunction("sysdatetimeoffset", NHibernateUtil.DateTimeOffset, true));
47+
if (!KeepDateTime)
48+
{
49+
RegisterFunction(
50+
"current_timestamp",
51+
new NoArgSQLFunction("sysdatetime", NHibernateUtil.DateTime, true));
52+
}
53+
RegisterFunction(
54+
"current_timestamp_offset",
55+
new NoArgSQLFunction("sysdatetimeoffset", NHibernateUtil.DateTimeOffset, true));
2856
}
2957

3058
protected override void RegisterKeywords()
@@ -42,21 +70,26 @@ protected override void RegisterDefaultProperties()
4270
}
4371

4472
public override string CurrentTimestampSQLFunctionName =>
45-
"SYSDATETIME()";
73+
KeepDateTime ? base.CurrentTimestampSQLFunctionName : "SYSDATETIME()";
4674

4775
public override long TimestampResolutionInTicks =>
48-
// MS SQL resolution with datetime2 is 100ns, one tick.
49-
1;
76+
KeepDateTime
77+
? base.TimestampResolutionInTicks
78+
// MS SQL resolution with datetime2 is 100ns, one tick.
79+
: 1;
5080

5181
/// <inheritdoc />
5282
public override SqlType[] RefineSqlTypes(IType type, SqlType[] types)
5383
{
54-
switch (type)
84+
if (!KeepDateTime)
5585
{
56-
// Switch built-in DateTime types and their descendants to DateTime2.
57-
case DateTimeType _:
58-
case TimestampType _:
59-
return new[] { SqlTypeFactory.DateTime2 };
86+
switch (type)
87+
{
88+
// Switch built-in DateTime types and their descendants to DateTime2.
89+
case DateTimeType _:
90+
case TimestampType _:
91+
return new[] { SqlTypeFactory.DateTime2 };
92+
}
6093
}
6194
return base.RefineSqlTypes(type, types);
6295
}

src/NHibernate/nhibernate-configuration.xsd

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@
161161
</xs:documentation>
162162
</xs:annotation>
163163
</xs:enumeration>
164+
<xs:enumeration value="sql_types.keep_datetime">
165+
<xs:annotation>
166+
<xs:documentation>
167+
Disable switching built-in NHibernate date-time types from DbType.DateTime to DbType.DateTime2
168+
for dialects supporting datetime2.
169+
</xs:documentation>
170+
</xs:annotation>
171+
</xs:enumeration>
164172
</xs:restriction>
165173
</xs:simpleType>
166174
</xs:attribute>

0 commit comments

Comments
 (0)