55using System . Net ;
66using Azure . DataApiBuilder . Core . Services . OpenAPI ;
77using Azure . DataApiBuilder . Service . Exceptions ;
8+ using Microsoft . OData . Edm ;
89
910namespace Azure . DataApiBuilder . Core . Services
1011{
@@ -16,6 +17,10 @@ public static class TypeHelper
1617 {
1718 /// <summary>
1819 /// Maps .NET Framework types to DbType enum
20+ /// Not Adding a hard mapping for System.DateTime to DbType.DateTime as
21+ /// Hotchocolate only has Hotchocolate.Types.DateTime for DbType.DateTime/DateTime2/DateTimeOffset,
22+ /// which throws error when inserting/updating dateTime values due to type mismatch.
23+ /// Therefore, seperate logic exists for proper mapping conversion in BaseSqlQueryStructure.
1924 /// </summary>
2025 private static Dictionary < Type , DbType > _systemTypeToDbTypeMap = new ( )
2126 {
@@ -34,21 +39,10 @@ public static class TypeHelper
3439 [ typeof ( string ) ] = DbType . String ,
3540 [ typeof ( char ) ] = DbType . StringFixedLength ,
3641 [ typeof ( Guid ) ] = DbType . Guid ,
42+ [ typeof ( DateTimeOffset ) ] = DbType . DateTimeOffset ,
3743 [ typeof ( byte [ ] ) ] = DbType . Binary ,
38- [ typeof ( byte ? ) ] = DbType . Byte ,
39- [ typeof ( sbyte ? ) ] = DbType . SByte ,
40- [ typeof ( short ? ) ] = DbType . Int16 ,
41- [ typeof ( ushort ? ) ] = DbType . UInt16 ,
42- [ typeof ( int ? ) ] = DbType . Int32 ,
43- [ typeof ( uint ? ) ] = DbType . UInt32 ,
44- [ typeof ( long ? ) ] = DbType . Int64 ,
45- [ typeof ( ulong ? ) ] = DbType . UInt64 ,
46- [ typeof ( float ? ) ] = DbType . Single ,
47- [ typeof ( double ? ) ] = DbType . Double ,
48- [ typeof ( decimal ? ) ] = DbType . Decimal ,
49- [ typeof ( bool ? ) ] = DbType . Boolean ,
50- [ typeof ( char ? ) ] = DbType . StringFixedLength ,
51- [ typeof ( Guid ? ) ] = DbType . Guid ,
44+ [ typeof ( TimeOnly ) ] = DbType . Time ,
45+ [ typeof ( TimeSpan ) ] = DbType . Time ,
5246 [ typeof ( object ) ] = DbType . Object
5347 } ;
5448
@@ -77,6 +71,7 @@ public static class TypeHelper
7771 [ typeof ( Guid ) ] = JsonDataType . String ,
7872 [ typeof ( byte [ ] ) ] = JsonDataType . String ,
7973 [ typeof ( TimeSpan ) ] = JsonDataType . String ,
74+ [ typeof ( TimeOnly ) ] = JsonDataType . String ,
8075 [ typeof ( object ) ] = JsonDataType . Object ,
8176 [ typeof ( DateTime ) ] = JsonDataType . String ,
8277 [ typeof ( DateTimeOffset ) ] = JsonDataType . String
@@ -108,14 +103,51 @@ public static class TypeHelper
108103 [ SqlDbType . SmallInt ] = typeof ( short ) ,
109104 [ SqlDbType . SmallMoney ] = typeof ( decimal ) ,
110105 [ SqlDbType . Text ] = typeof ( string ) ,
111- [ SqlDbType . Time ] = typeof ( TimeSpan ) ,
106+ [ SqlDbType . Time ] = typeof ( TimeOnly ) ,
112107 [ SqlDbType . Timestamp ] = typeof ( byte [ ] ) ,
113108 [ SqlDbType . TinyInt ] = typeof ( byte ) ,
114109 [ SqlDbType . UniqueIdentifier ] = typeof ( Guid ) ,
115110 [ SqlDbType . VarBinary ] = typeof ( byte [ ] ) ,
116111 [ SqlDbType . VarChar ] = typeof ( string )
117112 } ;
118113
114+ /// <summary>
115+ /// Given the system type, returns the corresponding primitive type kind.
116+ /// </summary>
117+ /// <param name="columnSystemType">Type of the column.</param>
118+ /// <returns>EdmPrimitiveTypeKind</returns>
119+ /// <exception cref="ArgumentException">Throws when the column</exception>
120+ public static EdmPrimitiveTypeKind GetEdmPrimitiveTypeFromSystemType ( Type columnSystemType )
121+ {
122+ if ( columnSystemType . IsArray )
123+ {
124+ columnSystemType = columnSystemType . GetElementType ( ) ! ;
125+ }
126+
127+ EdmPrimitiveTypeKind type = columnSystemType . Name switch
128+ {
129+ "String" => EdmPrimitiveTypeKind . String ,
130+ "Guid" => EdmPrimitiveTypeKind . Guid ,
131+ "Byte" => EdmPrimitiveTypeKind . Byte ,
132+ "Int16" => EdmPrimitiveTypeKind . Int16 ,
133+ "Int32" => EdmPrimitiveTypeKind . Int32 ,
134+ "Int64" => EdmPrimitiveTypeKind . Int64 ,
135+ "Single" => EdmPrimitiveTypeKind . Single ,
136+ "Double" => EdmPrimitiveTypeKind . Double ,
137+ "Decimal" => EdmPrimitiveTypeKind . Decimal ,
138+ "Boolean" => EdmPrimitiveTypeKind . Boolean ,
139+ "DateTime" => EdmPrimitiveTypeKind . DateTimeOffset ,
140+ "DateTimeOffset" => EdmPrimitiveTypeKind . DateTimeOffset ,
141+ "Date" => EdmPrimitiveTypeKind . Date ,
142+ "TimeOnly" => EdmPrimitiveTypeKind . TimeOfDay ,
143+ "TimeSpan" => EdmPrimitiveTypeKind . TimeOfDay ,
144+ _ => throw new ArgumentException ( $ "Column type" +
145+ $ " { columnSystemType . Name } not yet supported.")
146+ } ;
147+
148+ return type ;
149+ }
150+
119151 /// <summary>
120152 /// Converts the .NET Framework (System/CLR) type to JsonDataType.
121153 /// Primitive data types in the OpenAPI standard (OAS) are based on the types supported
@@ -151,6 +183,15 @@ public static JsonDataType GetJsonDataTypeFromSystemType(Type type)
151183 /// <returns>DbType for the given system type. Null when no mapping exists.</returns>
152184 public static DbType ? GetDbTypeFromSystemType ( Type systemType )
153185 {
186+ // Get the underlying type argument if the 'systemType' argument is a nullable type.
187+ Type ? nullableUnderlyingType = Nullable . GetUnderlyingType ( systemType ) ;
188+
189+ // Will not be null when the input argument 'systemType' is a closed generic nullable type.
190+ if ( nullableUnderlyingType is not null )
191+ {
192+ systemType = nullableUnderlyingType ;
193+ }
194+
154195 if ( ! _systemTypeToDbTypeMap . TryGetValue ( systemType , out DbType dbType ) )
155196 {
156197 return null ;
0 commit comments