diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index bc755d3486..adcd941afb 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -648,6 +648,9 @@ + + + diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 49327a4cdd..d255f7ba74 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -6085,7 +6085,11 @@ internal bool TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, int length, T } else { +#if NET7_0_OR_GREATER + value.SqlBinary = SqlBinary.WrapBytes(b); +#else value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(b, true); // doesn't copy the byte array +#endif } break; @@ -6378,7 +6382,11 @@ internal bool TryReadSqlValueInternal(SqlBuffer value, byte tdsType, int length, { return false; } +#if NET7_0_OR_GREATER + value.SqlBinary = SqlBinary.WrapBytes(b); +#else value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(b, true); +#endif break; } @@ -7244,18 +7252,23 @@ internal byte[] SerializeSqlDecimal(SqlDecimal d, TdsParserStateObject stateObj) else bytes[current++] = 0; - uint data1, data2, data3, data4; - SqlTypeWorkarounds.SqlDecimalExtractData(d, out data1, out data2, out data3, out data4); - byte[] bytesPart = SerializeUnsignedInt(data1, stateObj); + + Span data = stackalloc uint[4]; +#if NET7_0_OR_GREATER + d.WriteTdsValue(data); +#else + SqlTypeWorkarounds.SqlDecimalExtractData(d, out data[0], out data[1], out data[2], out data[3]); +#endif + byte[] bytesPart = SerializeUnsignedInt(data[0], stateObj); Buffer.BlockCopy(bytesPart, 0, bytes, current, 4); current += 4; - bytesPart = SerializeUnsignedInt(data2, stateObj); + bytesPart = SerializeUnsignedInt(data[1], stateObj); Buffer.BlockCopy(bytesPart, 0, bytes, current, 4); current += 4; - bytesPart = SerializeUnsignedInt(data3, stateObj); + bytesPart = SerializeUnsignedInt(data[2], stateObj); Buffer.BlockCopy(bytesPart, 0, bytes, current, 4); current += 4; - bytesPart = SerializeUnsignedInt(data4, stateObj); + bytesPart = SerializeUnsignedInt(data[3], stateObj); Buffer.BlockCopy(bytesPart, 0, bytes, current, 4); return bytes; @@ -7269,12 +7282,16 @@ internal void WriteSqlDecimal(SqlDecimal d, TdsParserStateObject stateObj) else stateObj.WriteByte(0); - uint data1, data2, data3, data4; - SqlTypeWorkarounds.SqlDecimalExtractData(d, out data1, out data2, out data3, out data4); - WriteUnsignedInt(data1, stateObj); - WriteUnsignedInt(data2, stateObj); - WriteUnsignedInt(data3, stateObj); - WriteUnsignedInt(data4, stateObj); + Span data = stackalloc uint[4]; +#if NET7_0_OR_GREATER + d.WriteTdsValue(data); +#else + SqlTypeWorkarounds.SqlDecimalExtractData(d, out data[0], out data[1], out data[2], out data[3]); +#endif + WriteUnsignedInt(data[0], stateObj); + WriteUnsignedInt(data[1], stateObj); + WriteUnsignedInt(data[2], stateObj); + WriteUnsignedInt(data[3], stateObj); } private byte[] SerializeDecimal(decimal value, TdsParserStateObject stateObj) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlTypeWorkarounds.netcore.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlTypeWorkarounds.netcore.cs index 43ed8bbee4..7ce991530a 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlTypeWorkarounds.netcore.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlTypeWorkarounds.netcore.cs @@ -122,31 +122,5 @@ private struct SqlBinaryCaster internal SqlBinaryLookalike Fake; } #endregion - - #region Work around inability to access SqlGuid.ctor(byte[], bool) - internal static SqlGuid SqlGuidCtor(byte[] value, bool ignored) - { - // Construct a SqlGuid without allocating/copying the byte[]. This provides - // the same behavior as SqlGuid.ctor(byte[], bool). - var c = default(SqlGuidCaster); - c.Fake._value = value; - return c.Real; - } - - [StructLayout(LayoutKind.Sequential)] - private struct SqlGuidLookalike - { - internal byte[] _value; - } - - [StructLayout(LayoutKind.Explicit)] - private struct SqlGuidCaster - { - [FieldOffset(0)] - internal SqlGuid Real; - [FieldOffset(0)] - internal SqlGuidLookalike Fake; - } - #endregion } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs index 0548bbf126..61bcec417f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs @@ -3158,7 +3158,11 @@ private static SqlMoney GetSqlMoney_Unchecked(SmiEventSink_Default sink, ITypedG long temp = getters.GetInt64(sink, ordinal); sink.ProcessMessagesAndThrow(); +#if NETCOREAPP && NET7_0_OR_GREATER + return SqlMoney.FromTdsValue(temp); +#else return SqlTypeWorkarounds.SqlMoneyCtor(temp, 1 /* ignored */ ); +#endif } private static SqlXml GetSqlXml_Unchecked(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiContext context) @@ -3638,7 +3642,11 @@ private static void SetSqlMoney_Unchecked(SmiEventSink_Default sink, ITypedSette sink.ProcessMessagesAndThrow(); } +#if NET7_0_OR_GREATER + setters.SetInt64(sink, ordinal, value.GetTdsValue()); +#else setters.SetInt64(sink, ordinal, SqlTypeWorkarounds.SqlMoneyToSqlInternalRepresentation(value)); +#endif } sink.ProcessMessagesAndThrow(); } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs index 686c5157ef..9cfc077da4 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs @@ -886,7 +886,11 @@ internal SqlMoney SqlMoney { return SqlMoney.Null; } +#if NETCOREAPP && NET7_0_OR_GREATER + return SqlMoney.FromTdsValue(_value._int64); +#else return SqlTypeWorkarounds.SqlMoneyCtor(_value._int64, 1/*ignored*/); +#endif } return (SqlMoney)SqlValue; // anything else we haven't thought of goes through boxing. }