@@ -637,116 +637,124 @@ internal void AppendBinary(ByteBufferWriter writer, StatementPreparerOptions opt
637
637
{
638
638
// stored in "null bitmap" only
639
639
}
640
- else if ( Value is string stringValue )
640
+ else
641
+ {
642
+ AppendBinary ( writer , Value , options ) ;
643
+ }
644
+ }
645
+
646
+ private void AppendBinary ( ByteBufferWriter writer , object value , StatementPreparerOptions options )
647
+ {
648
+ if ( value is string stringValue )
641
649
{
642
650
writer . WriteLengthEncodedString ( stringValue ) ;
643
651
}
644
- else if ( Value is char charValue )
652
+ else if ( value is char charValue )
645
653
{
646
654
writer . WriteLengthEncodedString ( charValue . ToString ( ) ) ;
647
655
}
648
- else if ( Value is sbyte sbyteValue )
656
+ else if ( value is sbyte sbyteValue )
649
657
{
650
658
writer . Write ( unchecked ( ( byte ) sbyteValue ) ) ;
651
659
}
652
- else if ( Value is byte byteValue )
660
+ else if ( value is byte byteValue )
653
661
{
654
662
writer . Write ( byteValue ) ;
655
663
}
656
- else if ( Value is bool boolValue )
664
+ else if ( value is bool boolValue )
657
665
{
658
666
writer . Write ( ( byte ) ( boolValue ? 1 : 0 ) ) ;
659
667
}
660
- else if ( Value is short shortValue )
668
+ else if ( value is short shortValue )
661
669
{
662
670
writer . Write ( unchecked ( ( ushort ) shortValue ) ) ;
663
671
}
664
- else if ( Value is ushort ushortValue )
672
+ else if ( value is ushort ushortValue )
665
673
{
666
674
writer . Write ( ushortValue ) ;
667
675
}
668
- else if ( Value is int intValue )
676
+ else if ( value is int intValue )
669
677
{
670
678
writer . Write ( intValue ) ;
671
679
}
672
- else if ( Value is uint uintValue )
680
+ else if ( value is uint uintValue )
673
681
{
674
682
writer . Write ( uintValue ) ;
675
683
}
676
- else if ( Value is long longValue )
684
+ else if ( value is long longValue )
677
685
{
678
686
writer . Write ( unchecked ( ( ulong ) longValue ) ) ;
679
687
}
680
- else if ( Value is ulong ulongValue )
688
+ else if ( value is ulong ulongValue )
681
689
{
682
690
writer . Write ( ulongValue ) ;
683
691
}
684
- else if ( Value is byte [ ] byteArrayValue )
692
+ else if ( value is byte [ ] byteArrayValue )
685
693
{
686
694
writer . WriteLengthEncodedInteger ( unchecked ( ( ulong ) byteArrayValue . Length ) ) ;
687
695
writer . Write ( byteArrayValue ) ;
688
696
}
689
- else if ( Value is ReadOnlyMemory < byte > readOnlyMemoryValue )
697
+ else if ( value is ReadOnlyMemory < byte > readOnlyMemoryValue )
690
698
{
691
699
writer . WriteLengthEncodedInteger ( unchecked ( ( ulong ) readOnlyMemoryValue . Length ) ) ;
692
700
writer . Write ( readOnlyMemoryValue . Span ) ;
693
701
}
694
- else if ( Value is Memory < byte > memoryValue )
702
+ else if ( value is Memory < byte > memoryValue )
695
703
{
696
704
writer . WriteLengthEncodedInteger ( unchecked ( ( ulong ) memoryValue . Length ) ) ;
697
705
writer . Write ( memoryValue . Span ) ;
698
706
}
699
- else if ( Value is ArraySegment < byte > arraySegmentValue )
707
+ else if ( value is ArraySegment < byte > arraySegmentValue )
700
708
{
701
709
writer . WriteLengthEncodedInteger ( unchecked ( ( ulong ) arraySegmentValue . Count ) ) ;
702
710
writer . Write ( arraySegmentValue ) ;
703
711
}
704
- else if ( Value is MySqlGeometry geometry )
712
+ else if ( value is MySqlGeometry geometry )
705
713
{
706
714
writer . WriteLengthEncodedInteger ( unchecked ( ( ulong ) geometry . ValueSpan . Length ) ) ;
707
715
writer . Write ( geometry . ValueSpan ) ;
708
716
}
709
- else if ( Value is MemoryStream memoryStream )
717
+ else if ( value is MemoryStream memoryStream )
710
718
{
711
719
if ( ! memoryStream . TryGetBuffer ( out var streamBuffer ) )
712
720
streamBuffer = new ArraySegment < byte > ( memoryStream . ToArray ( ) ) ;
713
721
writer . WriteLengthEncodedInteger ( unchecked ( ( ulong ) streamBuffer . Count ) ) ;
714
722
writer . Write ( streamBuffer ) ;
715
723
}
716
- else if ( Value is float floatValue )
724
+ else if ( value is float floatValue )
717
725
{
718
726
writer . Write ( BitConverter . GetBytes ( floatValue ) ) ;
719
727
}
720
- else if ( Value is double doubleValue )
728
+ else if ( value is double doubleValue )
721
729
{
722
730
writer . Write ( unchecked ( ( ulong ) BitConverter . DoubleToInt64Bits ( doubleValue ) ) ) ;
723
731
}
724
- else if ( Value is decimal decimalValue )
732
+ else if ( value is decimal decimalValue )
725
733
{
726
734
writer . WriteLengthEncodedAsciiString ( decimalValue . ToString ( CultureInfo . InvariantCulture ) ) ;
727
735
}
728
- else if ( Value is BigInteger bigInteger )
736
+ else if ( value is BigInteger bigInteger )
729
737
{
730
738
writer . WriteLengthEncodedAsciiString ( bigInteger . ToString ( CultureInfo . InvariantCulture ) ) ;
731
739
}
732
- else if ( Value is MySqlDateTime mySqlDateTimeValue )
740
+ else if ( value is MySqlDateTime mySqlDateTimeValue )
733
741
{
734
742
if ( mySqlDateTimeValue . IsValidDateTime )
735
743
WriteDateTime ( writer , mySqlDateTimeValue . GetDateTime ( ) ) ;
736
744
else
737
745
writer . Write ( ( byte ) 0 ) ;
738
746
}
739
- else if ( Value is MySqlDecimal mySqlDecimal )
747
+ else if ( value is MySqlDecimal mySqlDecimal )
740
748
{
741
749
writer . WriteLengthEncodedAsciiString ( mySqlDecimal . ToString ( ) ) ;
742
750
}
743
751
#if NET6_0_OR_GREATER
744
- else if ( Value is DateOnly dateOnlyValue)
752
+ else if ( value is DateOnly dateOnlyValue)
745
753
{
746
754
WriteDateOnly ( writer , dateOnlyValue ) ;
747
755
}
748
756
#endif
749
- else if ( Value is DateTime dateTimeValue)
757
+ else if ( value is DateTime dateTimeValue)
750
758
{
751
759
if ( ( options & StatementPreparerOptions . DateTimeUtc ) != 0 && dateTimeValue . Kind == DateTimeKind . Local )
752
760
throw new MySqlException ( $ "DateTime.Kind must not be Local when DateTimeKind setting is Utc (parameter name: { ParameterName } )") ;
@@ -755,22 +763,22 @@ internal void AppendBinary(ByteBufferWriter writer, StatementPreparerOptions opt
755
763
756
764
WriteDateTime ( writer , dateTimeValue ) ;
757
765
}
758
- else if ( Value is DateTimeOffset dateTimeOffsetValue)
766
+ else if ( value is DateTimeOffset dateTimeOffsetValue)
759
767
{
760
768
// store as UTC as it will be read as such when deserialized from a timespan column
761
769
WriteDateTime ( writer , dateTimeOffsetValue . UtcDateTime ) ;
762
770
}
763
771
#if NET6_0_OR_GREATER
764
- else if ( Value is TimeOnly timeOnlyValue)
772
+ else if ( value is TimeOnly timeOnlyValue)
765
773
{
766
774
WriteTime ( writer , timeOnlyValue . ToTimeSpan ( ) ) ;
767
775
}
768
776
#endif
769
- else if ( Value is TimeSpan ts)
777
+ else if ( value is TimeSpan ts)
770
778
{
771
779
WriteTime ( writer , ts ) ;
772
780
}
773
- else if ( Value is Guid guidValue)
781
+ else if ( value is Guid guidValue)
774
782
{
775
783
StatementPreparerOptions guidOptions = options & StatementPreparerOptions . GuidFormatMask ;
776
784
if ( guidOptions is StatementPreparerOptions . GuidFormatBinary16 or StatementPreparerOptions . GuidFormatTimeSwapBinary16 or StatementPreparerOptions . GuidFormatLittleEndianBinary16 )
@@ -817,53 +825,55 @@ internal void AppendBinary(ByteBufferWriter writer, StatementPreparerOptions opt
817
825
writer . Advance ( guidLength ) ;
818
826
}
819
827
}
820
- else if ( Value is ReadOnlyMemory< char > readOnlyMemoryChar)
828
+ else if ( value is ReadOnlyMemory< char > readOnlyMemoryChar)
821
829
{
822
830
writer. WriteLengthEncodedString( readOnlyMemoryChar . Span ) ;
823
831
}
824
- else if ( Value is Memory< char > memoryChar)
832
+ else if ( value is Memory< char > memoryChar)
825
833
{
826
834
writer. WriteLengthEncodedString ( memoryChar . Span ) ;
827
835
}
828
- else if ( Value is StringBuilder stringBuilder)
836
+ else if ( value is StringBuilder stringBuilder)
829
837
{
830
838
writer . WriteLengthEncodedString ( stringBuilder ) ;
831
839
}
832
- else if ( ( MySqlDbType is MySqlDbType. String or MySqlDbType. VarChar) && HasSetDbType && Value is Enum stringEnumValue)
840
+ else if ( ( MySqlDbType is MySqlDbType. String or MySqlDbType. VarChar) && HasSetDbType && value is Enum stringEnumValue)
833
841
{
834
842
writer. WriteLengthEncodedString( stringEnumValue . ToString ( "G ") ) ;
835
843
}
836
- else if ( Value is Enum )
844
+ else if ( value is Enum )
837
845
{
838
- writer . Write ( Convert . ToInt32 ( Value , CultureInfo . InvariantCulture ) ) ;
846
+ // using the underlying type matches the log in TypeMapper.GetDbTypeMapping, which controls the column type value that was sent to the server
847
+ var underlyingValue = Convert . ChangeType ( value , Enum . GetUnderlyingType ( value . GetType ( ) ) , CultureInfo . InvariantCulture ) ;
848
+ AppendBinary ( writer , underlyingValue , options ) ;
839
849
}
840
850
else if ( MySqlDbType == MySqlDbType . Int16 )
841
851
{
842
- writer . Write ( ( ushort ) ( short ) Value ) ;
852
+ writer . Write ( ( ushort ) ( short ) value ) ;
843
853
}
844
854
else if ( MySqlDbType == MySqlDbType . UInt16 )
845
855
{
846
- writer . Write ( ( ushort ) Value ) ;
856
+ writer . Write ( ( ushort ) value ) ;
847
857
}
848
858
else if ( MySqlDbType == MySqlDbType . Int32 )
849
859
{
850
- writer . Write ( ( int ) Value ) ;
860
+ writer . Write ( ( int ) value ) ;
851
861
}
852
862
else if ( MySqlDbType == MySqlDbType . UInt32 )
853
863
{
854
- writer . Write ( ( uint ) Value ) ;
864
+ writer . Write ( ( uint ) value ) ;
855
865
}
856
866
else if ( MySqlDbType == MySqlDbType . Int64 )
857
867
{
858
- writer . Write ( ( ulong ) ( long ) Value ) ;
868
+ writer . Write ( ( ulong ) ( long ) value ) ;
859
869
}
860
870
else if ( MySqlDbType == MySqlDbType . UInt64 )
861
871
{
862
- writer . Write ( ( ulong ) Value ) ;
872
+ writer . Write ( ( ulong ) value ) ;
863
873
}
864
874
else
865
875
{
866
- throw new NotSupportedException ( $ "Parameter type { Value . GetType ( ) . Name } is not supported; see https://fl.vu/mysql-param-type. Value: { Value } ") ;
876
+ throw new NotSupportedException ( $ "Parameter type { value . GetType ( ) . Name } is not supported; see https://fl.vu/mysql-param-type. Value: { value } ") ;
867
877
}
868
878
}
869
879
0 commit comments