diff --git a/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/Connection.cs b/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/Connection.cs index 6d8e8cccf1..82798b1af6 100644 --- a/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/Connection.cs +++ b/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/Connection.cs @@ -52,9 +52,7 @@ public override void Commit() EnsureTransactionIsActive(); try { - if (!IsTransactionCompleted()) { - ActiveTransaction.Commit(); - } + ActiveTransaction.Commit(); } finally { ActiveTransaction.Dispose(); @@ -67,9 +65,7 @@ public override async Task CommitAsync(CancellationToken token = default) EnsureIsNotDisposed(); EnsureTransactionIsActive(); try { - if (!IsTransactionCompleted()) { - await ActiveTransaction.CommitAsync(token).ConfigureAwait(false); - } + await ActiveTransaction.CommitAsync(token).ConfigureAwait(false); } finally { await ActiveTransaction.DisposeAsync().ConfigureAwait(false); @@ -83,9 +79,7 @@ public override void Rollback() EnsureTransactionIsActive(); try { - if (!IsTransactionCompleted()) { - ActiveTransaction.Rollback(); - } + ActiveTransaction.Rollback(); } finally { ActiveTransaction.Dispose(); @@ -98,9 +92,7 @@ public override async Task RollbackAsync(CancellationToken token = default) EnsureIsNotDisposed(); EnsureTransactionIsActive(); try { - if (!IsTransactionCompleted()) { - await ActiveTransaction.RollbackAsync(token).ConfigureAwait(false); - } + await ActiveTransaction.RollbackAsync(token).ConfigureAwait(false); } finally { await ActiveTransaction.DisposeAsync().ConfigureAwait(false); @@ -182,11 +174,7 @@ private async Task ExecuteNonQueryAsync(string commandText, CancellationToken to await command.ExecuteNonQueryAsync(token).ConfigureAwait(false); } } - - private bool IsTransactionCompleted() - { - return activeTransaction != null && activeTransaction.IsCompleted; - } + // Constructors diff --git a/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v10_0/TypeMapper.cs b/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v10_0/TypeMapper.cs index 9e1908f62f..75b5f9fdd4 100644 --- a/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v10_0/TypeMapper.cs +++ b/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v10_0/TypeMapper.cs @@ -4,11 +4,38 @@ // Created by: Alexey Kulakov // Created: 2019.09.25 +using System; +using System.Data.Common; +using System.Security; +using Npgsql; +using NpgsqlTypes; + namespace Xtensive.Sql.Drivers.PostgreSql.v10_0 { internal class TypeMapper : v9_1.TypeMapper { // Constructors + + [SecuritySafeCritical] + public override void BindDateTime(DbParameter parameter, object value) + { + var nativeParameter = (NpgsqlParameter) parameter; + nativeParameter.NpgsqlDbType = NpgsqlDbType.Timestamp; + + if (value is DateTime {Kind: DateTimeKind.Utc} dateTime) { + value = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified); + } + nativeParameter.NpgsqlValue = value ?? DBNull.Value; + } + + public override SqlValueType MapDateTime(int? length, int? precision, int? scale) => new (SqlType.DateTime); + + public override object ReadDateTime(DbDataReader reader, int index) + { + var nativeReader = (NpgsqlDataReader) reader; + var value = nativeReader.GetFieldValue(index); + return value; + } public TypeMapper(SqlDriver driver) : base(driver) diff --git a/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v8_0/TypeMapper.cs b/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v8_0/TypeMapper.cs index 4e419085d3..aad930805f 100644 --- a/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v8_0/TypeMapper.cs +++ b/Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v8_0/TypeMapper.cs @@ -129,6 +129,10 @@ public override void BindDateTimeOffset(DbParameter parameter, object value) { var nativeParameter = (NpgsqlParameter) parameter; nativeParameter.NpgsqlDbType = NpgsqlDbType.TimestampTz; + if (value is DateTimeOffset dateTimeOffset) { + var localTimeTicks = dateTimeOffset.UtcTicks; + value = new DateTimeOffset(localTimeTicks, TimeSpan.Zero); + } nativeParameter.NpgsqlValue = value ?? DBNull.Value; } @@ -195,7 +199,7 @@ public override object ReadDateTimeOffset(DbDataReader reader, int index) { var nativeReader = (NpgsqlDataReader) reader; var value = nativeReader.GetFieldValue(index); - return value; + return value.ToLocalTime(); } // Constructors diff --git a/Orm/Xtensive.Orm.PostgreSql/Xtensive.Orm.PostgreSql.csproj b/Orm/Xtensive.Orm.PostgreSql/Xtensive.Orm.PostgreSql.csproj index 47da25e64c..871f3ce324 100644 --- a/Orm/Xtensive.Orm.PostgreSql/Xtensive.Orm.PostgreSql.csproj +++ b/Orm/Xtensive.Orm.PostgreSql/Xtensive.Orm.PostgreSql.csproj @@ -21,7 +21,7 @@ TRACE - + diff --git a/Orm/Xtensive.Orm.Tests/Xtensive.Orm.Tests.csproj b/Orm/Xtensive.Orm.Tests/Xtensive.Orm.Tests.csproj index dcbc9fe682..e93fc7aaec 100644 --- a/Orm/Xtensive.Orm.Tests/Xtensive.Orm.Tests.csproj +++ b/Orm/Xtensive.Orm.Tests/Xtensive.Orm.Tests.csproj @@ -14,7 +14,7 @@ - + @@ -102,4 +102,4 @@ TwoPartsModel.tt - \ No newline at end of file +