Skip to content

Commit 22db119

Browse files
committed
Implement MySqlParameter.MySqlDbType property.
Use TypeMapper to map between DbType and MySqlDbType.
1 parent a2955d0 commit 22db119

File tree

7 files changed

+136
-122
lines changed

7 files changed

+136
-122
lines changed

src/MySqlConnector/MySqlClient/Caches/CachedProcedure.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
44
using System.Data;
@@ -13,7 +13,7 @@ internal class CachedProcedure
1313
{
1414
internal static async Task<CachedProcedure> FillAsync(IOBehavior ioBehavior, MySqlConnection connection, string schema, string component, CancellationToken cancellationToken)
1515
{
16-
var cmd = (MySqlCommand) connection.CreateCommand();
16+
var cmd = connection.CreateCommand();
1717

1818
cmd.CommandText = @"SELECT ORDINAL_POSITION, PARAMETER_MODE, PARAMETER_NAME, DATA_TYPE, DTD_IDENTIFIER
1919
FROM information_schema.parameters
@@ -22,13 +22,11 @@ FROM information_schema.parameters
2222
cmd.Parameters.Add(new MySqlParameter
2323
{
2424
ParameterName = "@schema",
25-
DbType = DbType.String,
2625
Value = schema
2726
});
2827
cmd.Parameters.Add(new MySqlParameter
2928
{
3029
ParameterName = "@component",
31-
DbType = DbType.String,
3230
Value = component
3331
});
3432

@@ -77,7 +75,7 @@ internal MySqlParameterCollection AlignParamsWithDb(MySqlParameterCollection par
7775

7876
if (!alignParam.HasSetDirection)
7977
alignParam.Direction = cachedParam.Direction;
80-
if (alignParam.DbType == default(DbType))
78+
if (!alignParam.HasSetDbType)
8179
alignParam.DbType = cachedParam.DbType;
8280

8381
// cached parameters are oredered by ordinal position

src/MySqlConnector/MySqlClient/CommandExecutors/StoredProcedureCommandExecutor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Data;
44
using System.Data.Common;
@@ -102,7 +102,7 @@ internal void SetParams()
102102
for (var i = 0; i < m_outParams.Count; i++)
103103
{
104104
var param = m_outParams[i];
105-
if (param.DbType != default(DbType))
105+
if (param.HasSetDbType)
106106
{
107107
var dbTypeMapping = TypeMapper.Mapper.GetDbTypeMapping(param.DbType);
108108
if (dbTypeMapping != null)

src/MySqlConnector/MySqlClient/MySqlConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ public override System.Data.DataTable GetSchema(string collectionName, string[]
267267
foreach (MySqlDbType mapItem in Enum.GetValues(typeof(MySqlDbType)))
268268
{
269269
var typeName = Enum.GetName(typeof(MySqlDbType), mapItem);
270-
var dbType = Types.TypeMapper.ConvertFromMySqlDbType(mapItem);
270+
var dbType = Types.TypeMapper.Mapper.GetDbTypeForMySqlDbType(mapItem);
271271
var map = Types.TypeMapper.Mapper.GetDbTypeMapping(dbType);
272272
if (map != null) // MySqlDbType.Set is not supported by the mapper.
273273
{

src/MySqlConnector/MySqlClient/MySqlParameter.cs

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,45 @@
22
using System.Data;
33
using System.Data.Common;
44
using System.IO;
5+
using MySql.Data.MySqlClient.Types;
56

67
namespace MySql.Data.MySqlClient
78
{
89
public sealed class MySqlParameter : DbParameter
910
{
1011
public MySqlParameter()
1112
{
13+
m_mySqlDbType = MySqlDbType.VarChar;
1214
}
1315

1416
public MySqlParameter(string name, object objValue)
1517
{
18+
m_mySqlDbType = MySqlDbType.VarChar;
1619
ParameterName = name;
1720
Value = objValue;
1821
}
1922

20-
public override DbType DbType { get; set; }
23+
public override DbType DbType
24+
{
25+
get => m_dbType;
26+
set
27+
{
28+
m_dbType = value;
29+
m_mySqlDbType = TypeMapper.Mapper.GetMySqlDbTypeForDbType(value);
30+
HasSetDbType = true;
31+
}
32+
}
33+
34+
public MySqlDbType MySqlDbType
35+
{
36+
get => m_mySqlDbType;
37+
set
38+
{
39+
m_dbType = TypeMapper.Mapper.GetDbTypeForMySqlDbType(value);
40+
m_mySqlDbType = value;
41+
HasSetDbType = true;
42+
}
43+
}
2144

2245
public override ParameterDirection Direction
2346
{
@@ -77,22 +100,14 @@ public override void ResetDbType()
77100
DbType = default(DbType);
78101
}
79102

80-
public MySqlDbType MySqlDbType {
81-
get {
82-
return Types.TypeMapper.ConverToMySqlDbType(DbType);
83-
}
84-
set {
85-
DbType = Types.TypeMapper.ConvertFromMySqlDbType(MySqlDbType);
86-
}
87-
}
88-
89-
90103
internal MySqlParameter WithParameterName(string parameterName) => new MySqlParameter(this, parameterName);
91104

92105
private MySqlParameter(MySqlParameter other, string parameterName)
93106
{
94-
DbType = other.DbType;
107+
m_dbType = other.m_dbType;
108+
m_mySqlDbType = other.m_mySqlDbType;
95109
m_direction = other.m_direction;
110+
HasSetDbType = other.HasSetDbType;
96111
IsNullable = other.IsNullable;
97112
Size = other.Size;
98113
ParameterName = parameterName ?? other.ParameterName;
@@ -105,6 +120,8 @@ private MySqlParameter(MySqlParameter other, string parameterName)
105120

106121
internal bool HasSetDirection => m_direction.HasValue;
107122

123+
internal bool HasSetDbType { get; set; }
124+
108125
internal string NormalizedParameterName { get; private set; }
109126

110127
internal void AppendSqlString(BinaryWriter writer, StatementPreparerOptions options)
@@ -190,27 +207,27 @@ internal void AppendSqlString(BinaryWriter writer, StatementPreparerOptions opti
190207
writer.WriteUtf8("'{0:D}'".FormatInvariant(guidValue));
191208
}
192209
}
193-
else if (DbType == DbType.Int16)
210+
else if (MySqlDbType == MySqlDbType.Int16)
194211
{
195212
writer.WriteUtf8("{0}".FormatInvariant((short) Value));
196213
}
197-
else if (DbType == DbType.UInt16)
214+
else if (MySqlDbType == MySqlDbType.UInt16)
198215
{
199216
writer.WriteUtf8("{0}".FormatInvariant((ushort) Value));
200217
}
201-
else if (DbType == DbType.Int32)
218+
else if (MySqlDbType == MySqlDbType.Int32)
202219
{
203220
writer.WriteUtf8("{0}".FormatInvariant((int) Value));
204221
}
205-
else if (DbType == DbType.UInt32)
222+
else if (MySqlDbType == MySqlDbType.UInt32)
206223
{
207224
writer.WriteUtf8("{0}".FormatInvariant((uint) Value));
208225
}
209-
else if (DbType == DbType.Int64)
226+
else if (MySqlDbType == MySqlDbType.Int64)
210227
{
211228
writer.WriteUtf8("{0}".FormatInvariant((long) Value));
212229
}
213-
else if (DbType == DbType.UInt64)
230+
else if (MySqlDbType == MySqlDbType.UInt64)
214231
{
215232
writer.WriteUtf8("{0}".FormatInvariant((ulong) Value));
216233
}
@@ -238,6 +255,8 @@ internal static string NormalizeParameterName(string name)
238255
return name.StartsWith("@", StringComparison.Ordinal) || name.StartsWith("?", StringComparison.Ordinal) ? name.Substring(1) : name;
239256
}
240257

258+
DbType m_dbType;
259+
MySqlDbType m_mySqlDbType;
241260
string m_name;
242261
ParameterDirection? m_direction;
243262
}

src/MySqlConnector/MySqlClient/Types/TypeMapper.cs

Lines changed: 23 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@ private TypeMapper()
3535
AddMySqlDbTypeMapping(new ColumnTypeMapping("TINYINT", typeByte, MySqlDbType.UByte, unsigned: true));
3636
AddMySqlDbTypeMapping(new ColumnTypeMapping("SMALLINT", typeShort, MySqlDbType.Int16, unsigned: false));
3737
AddMySqlDbTypeMapping(new ColumnTypeMapping("SMALLINT", typeUshort, MySqlDbType.UInt16, unsigned: true));
38-
AddMySqlDbTypeMapping(new ColumnTypeMapping("MEDIUMINT", typeInt, MySqlDbType.Int24, unsigned: false));
39-
AddMySqlDbTypeMapping(new ColumnTypeMapping("MEDIUMINT", typeUint, MySqlDbType.UInt24, unsigned: true));
4038
AddMySqlDbTypeMapping(new ColumnTypeMapping("INT", typeInt, MySqlDbType.Int32, unsigned: false));
4139
AddMySqlDbTypeMapping(new ColumnTypeMapping("INT", typeUint, MySqlDbType.UInt32, unsigned: true));
40+
AddMySqlDbTypeMapping(new ColumnTypeMapping("MEDIUMINT", typeInt, MySqlDbType.Int24, unsigned: false));
41+
AddMySqlDbTypeMapping(new ColumnTypeMapping("MEDIUMINT", typeUint, MySqlDbType.UInt24, unsigned: true));
4242
AddMySqlDbTypeMapping(new ColumnTypeMapping("BIGINT", typeLong, MySqlDbType.Int64, unsigned: false));
4343
AddMySqlDbTypeMapping(new ColumnTypeMapping("BIGINT", typeUlong, MySqlDbType.UInt64, unsigned: true));
4444
AddMySqlDbTypeMapping(new ColumnTypeMapping("BIT", typeUlong, MySqlDbType.Bit));
4545

4646
// decimals
47-
var typeDecimal = AddDbTypeMapping(new DbTypeMapping(typeof(decimal), new[] { DbType.Decimal }, convert: o => Convert.ToDecimal(o)));
47+
var typeDecimal = AddDbTypeMapping(new DbTypeMapping(typeof(decimal), new[] { DbType.Decimal, DbType.Currency, DbType.VarNumeric }, convert: o => Convert.ToDecimal(o)));
4848
var typeDouble = AddDbTypeMapping(new DbTypeMapping(typeof(double), new[] { DbType.Double }, convert: o => Convert.ToDouble(o)));
4949
var typeFloat = AddDbTypeMapping(new DbTypeMapping(typeof(float), new[] { DbType.Single }, convert: o => Convert.ToSingle(o)));
5050
AddMySqlDbTypeMapping(new ColumnTypeMapping("DECIMAL", typeDecimal, MySqlDbType.NewDecimal));
@@ -53,8 +53,9 @@ private TypeMapper()
5353
AddMySqlDbTypeMapping(new ColumnTypeMapping("FLOAT", typeFloat, MySqlDbType.Float));
5454

5555
// string
56-
var typeString = AddDbTypeMapping(new DbTypeMapping(typeof(string), new[] { DbType.String, DbType.StringFixedLength, DbType.AnsiString, DbType.AnsiStringFixedLength }, convert: o => Convert.ToString(o)));
57-
AddMySqlDbTypeMapping(new ColumnTypeMapping("CHAR", typeString, MySqlDbType.String));
56+
var typeFixedString = AddDbTypeMapping(new DbTypeMapping(typeof(string), new[] { DbType.StringFixedLength, DbType.AnsiStringFixedLength }, convert: Convert.ToString));
57+
var typeString = AddDbTypeMapping(new DbTypeMapping(typeof(string), new[] { DbType.String, DbType.AnsiString, DbType.Xml }, convert: Convert.ToString));
58+
AddMySqlDbTypeMapping(new ColumnTypeMapping("CHAR", typeFixedString, MySqlDbType.String));
5859
AddMySqlDbTypeMapping(new ColumnTypeMapping("VARCHAR", typeString, MySqlDbType.VarChar));
5960
AddMySqlDbTypeMapping(new ColumnTypeMapping("VARCHAR", typeString, MySqlDbType.VarString));
6061
AddMySqlDbTypeMapping(new ColumnTypeMapping("TINYTEXT", typeString, MySqlDbType.TinyText, simpleDataTypeName: "VARCHAR"));
@@ -67,10 +68,10 @@ private TypeMapper()
6768

6869
// binary
6970
var typeBinary = AddDbTypeMapping(new DbTypeMapping(typeof(byte[]), new[] { DbType.Binary }));
71+
AddMySqlDbTypeMapping(new ColumnTypeMapping("BLOB", typeBinary, MySqlDbType.Blob, binary: true, simpleDataTypeName: "BLOB"));
7072
AddMySqlDbTypeMapping(new ColumnTypeMapping("BINARY", typeBinary, MySqlDbType.Binary, binary: true, simpleDataTypeName: "BLOB"));
7173
AddMySqlDbTypeMapping(new ColumnTypeMapping("VARBINARY", typeBinary, MySqlDbType.VarBinary, binary: true, simpleDataTypeName: "BLOB"));
7274
AddMySqlDbTypeMapping(new ColumnTypeMapping("TINYBLOB", typeBinary, MySqlDbType.TinyBlob, binary: true, simpleDataTypeName: "BLOB"));
73-
AddMySqlDbTypeMapping(new ColumnTypeMapping("BLOB", typeBinary, MySqlDbType.Blob, binary: true, simpleDataTypeName: "BLOB"));
7475
AddMySqlDbTypeMapping(new ColumnTypeMapping("MEDIUMBLOB", typeBinary, MySqlDbType.MediumBlob, binary: true, simpleDataTypeName: "BLOB"));
7576
AddMySqlDbTypeMapping(new ColumnTypeMapping("LONGBLOB", typeBinary, MySqlDbType.LongBlob, binary: true, simpleDataTypeName: "BLOB"));
7677

@@ -85,10 +86,12 @@ private TypeMapper()
8586
AddMySqlDbTypeMapping(new ColumnTypeMapping("GEOMETRYCOLLECTION", typeBinary, MySqlDbType.Geometry, binary: true));
8687

8788
// date/time
88-
var typeDateTime = AddDbTypeMapping(new DbTypeMapping(typeof(DateTime), new[] { DbType.DateTime, DbType.Date, DbType.DateTime2, DbType.DateTimeOffset }));
89+
var typeDate = AddDbTypeMapping(new DbTypeMapping(typeof(DateTime), new[] { DbType.Date }));
90+
var typeDateTime = AddDbTypeMapping(new DbTypeMapping(typeof(DateTime), new[] { DbType.DateTime, DbType.DateTime2, DbType.DateTimeOffset }));
8991
var typeTime = AddDbTypeMapping(new DbTypeMapping(typeof(TimeSpan), new[] { DbType.Time }));
9092
AddMySqlDbTypeMapping(new ColumnTypeMapping("DATETIME", typeDateTime, MySqlDbType.DateTime));
91-
AddMySqlDbTypeMapping(new ColumnTypeMapping("DATE", typeDateTime, MySqlDbType.Date));
93+
AddMySqlDbTypeMapping(new ColumnTypeMapping("DATE", typeDate, MySqlDbType.Date));
94+
AddMySqlDbTypeMapping(new ColumnTypeMapping("DATE", typeDate, MySqlDbType.Newdate));
9295
AddMySqlDbTypeMapping(new ColumnTypeMapping("TIME", typeTime, MySqlDbType.Time));
9396
AddMySqlDbTypeMapping(new ColumnTypeMapping("TIMESTAMP", typeDateTime, MySqlDbType.Timestamp));
9497
AddMySqlDbTypeMapping(new ColumnTypeMapping("YEAR", typeInt, MySqlDbType.Year));
@@ -104,6 +107,18 @@ private TypeMapper()
104107

105108
public ColumnTypeMapping GetColumnMapping(MySqlDbType mySqlDbType) => m_mySqlDbTypeToColumnTypeMapping[mySqlDbType];
106109

110+
public DbType GetDbTypeForMySqlDbType(MySqlDbType mySqlDbType) => m_mySqlDbTypeToColumnTypeMapping[mySqlDbType].DbTypeMapping.DbTypes[0];
111+
112+
public MySqlDbType GetMySqlDbTypeForDbType(DbType dbType)
113+
{
114+
foreach (var pair in m_mySqlDbTypeToColumnTypeMapping)
115+
{
116+
if (pair.Value.DbTypeMapping.DbTypes.Contains(dbType))
117+
return pair.Key;
118+
}
119+
return MySqlDbType.VarChar;
120+
}
121+
107122
private DbTypeMapping AddDbTypeMapping(DbTypeMapping dbTypeMapping)
108123
{
109124
m_dbTypeMappingsByClrType[dbTypeMapping.ClrType] = dbTypeMapping;
@@ -244,89 +259,6 @@ public static MySqlDbType ConvertToMySqlDbType(ColumnDefinitionPayload columnDef
244259
}
245260
}
246261

247-
internal static MySqlDbType ConverToMySqlDbType(DbType dbtype)
248-
{
249-
switch (dbtype)
250-
{
251-
case DbType.AnsiString: return MySqlDbType.String;
252-
case DbType.Binary: return MySqlDbType.Binary;
253-
case DbType.Byte: return MySqlDbType.Byte;
254-
case DbType.Boolean: return MySqlDbType.Bit;
255-
case DbType.Currency: return MySqlDbType.Decimal;
256-
case DbType.Date: return MySqlDbType.Date;
257-
case DbType.DateTime: return MySqlDbType.DateTime;
258-
case DbType.Decimal: return MySqlDbType.Decimal;
259-
case DbType.Double: return MySqlDbType.Double;
260-
case DbType.Guid: return MySqlDbType.Guid;
261-
case DbType.Int16: return MySqlDbType.Int16;
262-
case DbType.Int32: return MySqlDbType.Int32;
263-
case DbType.Int64: return MySqlDbType.Int64;
264-
case DbType.Object: return MySqlDbType.Text;
265-
case DbType.SByte: return MySqlDbType.UByte;
266-
case DbType.Single: return MySqlDbType.Float;
267-
case DbType.String: return MySqlDbType.String;
268-
case DbType.Time: return MySqlDbType.Time;
269-
case DbType.UInt16: return MySqlDbType.UInt16;
270-
case DbType.UInt32: return MySqlDbType.UInt32;
271-
case DbType.UInt64: return MySqlDbType.UInt64;
272-
case DbType.VarNumeric: return MySqlDbType.Decimal;
273-
case DbType.AnsiStringFixedLength: return MySqlDbType.String;
274-
case DbType.StringFixedLength: return MySqlDbType.VarChar;
275-
case DbType.Xml: return MySqlDbType.Text;
276-
case DbType.DateTime2: return MySqlDbType.Newdate;
277-
case DbType.DateTimeOffset: return MySqlDbType.Timestamp;
278-
}
279-
throw new InvalidCastException("Never reached. " + dbtype.ToString());
280-
}
281-
internal static DbType ConvertFromMySqlDbType(MySqlDbType dbtype)
282-
{
283-
switch (dbtype)
284-
{
285-
case MySqlDbType.Decimal: return DbType.Decimal;
286-
case MySqlDbType.Byte: return DbType.Byte;
287-
case MySqlDbType.Int16: return DbType.Int16;
288-
case MySqlDbType.Int24: return DbType.Int32;
289-
case MySqlDbType.Int32: return DbType.Int32;
290-
case MySqlDbType.Int64: return DbType.Int64;
291-
case MySqlDbType.Float: return DbType.Single;
292-
case MySqlDbType.Double: return DbType.Double;
293-
case MySqlDbType.Timestamp: return DbType.DateTimeOffset;
294-
case MySqlDbType.Date: return DbType.Date;
295-
case MySqlDbType.Time: return DbType.Time;
296-
case MySqlDbType.DateTime: return DbType.DateTime;
297-
case MySqlDbType.Year: return DbType.Int16;
298-
case MySqlDbType.Newdate: return DbType.DateTime2;
299-
case MySqlDbType.VarString: return DbType.String;
300-
case MySqlDbType.Bit: return DbType.Boolean;
301-
case MySqlDbType.JSON: return DbType.String;
302-
case MySqlDbType.NewDecimal: return DbType.Decimal;
303-
case MySqlDbType.Enum: return DbType.Int16;
304-
case MySqlDbType.Set: return DbType.Object;
305-
case MySqlDbType.TinyBlob: return DbType.Binary;
306-
case MySqlDbType.MediumBlob: return DbType.Binary;
307-
case MySqlDbType.LongBlob: return DbType.Binary;
308-
case MySqlDbType.Blob: return DbType.Binary;
309-
case MySqlDbType.VarChar: return DbType.StringFixedLength;
310-
case MySqlDbType.String: return DbType.String;
311-
case MySqlDbType.Geometry: return DbType.Binary;
312-
case MySqlDbType.UByte: return DbType.SByte;
313-
case MySqlDbType.UInt16: return DbType.UInt16;
314-
case MySqlDbType.UInt24: return DbType.UInt32;
315-
case MySqlDbType.UInt32: return DbType.UInt32;
316-
case MySqlDbType.UInt64: return DbType.UInt64;
317-
case MySqlDbType.Binary: return DbType.Binary;
318-
case MySqlDbType.VarBinary: return DbType.Binary;
319-
case MySqlDbType.TinyText: return DbType.String;
320-
case MySqlDbType.MediumText: return DbType.String;
321-
case MySqlDbType.LongText: return DbType.String;
322-
case MySqlDbType.Text: return DbType.String;
323-
case MySqlDbType.Guid: return DbType.Guid;
324-
case MySqlDbType.Bool: return DbType.Boolean;
325-
case MySqlDbType.Null: return DbType.Object;
326-
}
327-
throw new InvalidCastException("Never reached. " + dbtype.ToString());
328-
}
329-
330262
internal IEnumerable<ColumnTypeMapping> GetColumnMappings()
331263
{
332264
return m_columnTypeMappingLookup.Values.AsEnumerable();

tests/MySqlConnector.Tests/TypeMapperTests.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ public class TypeMapperTests
2222
[InlineData(typeof(double), DbType.Double)]
2323
[InlineData(typeof(float), DbType.Single)]
2424
[InlineData(typeof(string), DbType.String)]
25-
[InlineData(typeof(string), DbType.StringFixedLength)]
2625
[InlineData(typeof(string), DbType.AnsiString)]
27-
[InlineData(typeof(string), DbType.AnsiStringFixedLength)]
2826
[InlineData(typeof(byte[]), DbType.Binary)]
29-
[InlineData(typeof(DateTime), DbType.Date)]
3027
[InlineData(typeof(DateTime), DbType.DateTime)]
3128
[InlineData(typeof(DateTime), DbType.DateTime2)]
3229
[InlineData(typeof(DateTime), DbType.DateTimeOffset)]
@@ -74,7 +71,7 @@ public void ConversionTest(object original, DbType dbType, object expected)
7471
[InlineData("decimal", false, 0, DbType.Decimal)]
7572
[InlineData("double", false, 0, DbType.Double)]
7673
[InlineData("float", false, 0, DbType.Single)]
77-
[InlineData("char", false, 0, DbType.String)]
74+
[InlineData("char", false, 0, DbType.StringFixedLength)]
7875
[InlineData("varchar", false, 0, DbType.String)]
7976
[InlineData("tinytext", false, 0, DbType.String)]
8077
[InlineData("text", false, 0, DbType.String)]
@@ -97,7 +94,7 @@ public void ConversionTest(object original, DbType dbType, object expected)
9794
[InlineData("multilinestring", false, 0, DbType.Binary)]
9895
[InlineData("multipolygon", false, 0, DbType.Binary)]
9996
[InlineData("datetime", false, 0, DbType.DateTime)]
100-
[InlineData("date", false, 0, DbType.DateTime)] // todo: this should be DbType.Date
97+
[InlineData("date", false, 0, DbType.Date)]
10198
[InlineData("time", false, 0, DbType.Time)]
10299
[InlineData("timestamp", false, 0, DbType.DateTime)]
103100
[InlineData("year", false, 0, DbType.Int32)]

0 commit comments

Comments
 (0)