MySQL表定义:
CREATE TABLE `table` (
`id` tinyint(1) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Auto-increment ID',
`data_provider_id` tinyint(1) unsigned NOT NULL COMMENT 'Data provider ID',
`is_active` bit(1) NOT NULL DEFAULT b'1' COMMENT '0 = retired source',
PRIMARY KEY (`id`),
KEY `DATA_PROVIDER_ID` (`data_provider_id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8
C#代码:
public static class MySqlConnector
{
public static DataTable QueryDatabase(
MySqlConnection mysqlConnection,
string mysqlQuery)
{
MySqlCommand mysqlCommand = new MySqlCommand(mysqlQuery, mysqlConnection);
MySqlDataReader mysqlDataReader = mysqlCommand.ExecuteReader();
DataTable dataTable = new DataTable();
dataTable.Load(mysqlDataReader);
return dataTable;
}
}
...
mysqlQuery = @"
SELECT
`id`,
`data_provider_id`,
`is_active`
FROM
`{0}`;
";
mysqlQuery = String.Format(mysqlQuery, tableName);
DataTable dt = MySqlConnector.QueryDatabase(mysqlConnection, mysqlQuery);
现在,当我在GetType()
字段上拨打dt
时,表示id
为Int32
(而不是Byte
),data_provider_id
为Byte
(令人惊讶的正确)和is_active
为Uint64
(而不是Boolean
)。
情况变得更糟。我有另一个表格,其中id
字段为int(1) unsigned
,而QueryDatabase()
仍将其作为已签名的int返回。
用于快速测试的PowerShell代码:
# Importing MySQL Connector.NET DLL.
$sMySqlServer = "server"
$sPath = "\\{0}\Connector.NET 6.9.7\Assemblies\v4.5\MySql.Data.dll" `
-f $sMySqlServer
Add-Type -Path $sPath
# Creating MySQL connection.
$sMySqlUser = "user"
$sMySqlPassword = "password"
$sMySqlDatabase = "test"
$sMySqlConnectionString = "server={0};uid={1};pwd={2};database={3};" `
-f $sMySqlServer, $sMySqlUser, $sMySqlPassword, $sMySqlDatabase
$oMySqlConnection = New-Object -TypeName MySql.Data.MySqlClient.MySqlConnection
$oMySqlConnection.ConnectionString = $sMySqlConnectionString
$oMySqlConnection.Open()
# Getting raw data.
$sMySqlQuery = "SELECT * FROM `table` ;"
$oMySqlCommand = New-Object -TypeName `
MySql.Data.MySqlClient.MySqlCommand($sMySqlQuery, $oMySqlConnection)
$oMySqlDataReader = $oMySqlCommand.ExecuteReader()
$oDataTable = New-Object -TypeName System.Data.DataTable
$oDataTable.Load($oMySqlDataReader)
$oDataTable | Get-Member
输出:
TypeName: System.Data.DataRow
Name MemberType Definition
---- ---------- ----------
AcceptChanges Method void AcceptChanges()
BeginEdit Method void BeginEdit()
CancelEdit Method void CancelEdit()
ClearErrors Method void ClearErrors()
Delete Method void Delete()
EndEdit Method void EndEdit()
Equals Method bool Equals(System.Object obj)
GetChildRows Method System.Data.DataRow[] GetChildRows(string relat...
GetColumnError Method string GetColumnError(int columnIndex), string ...
GetColumnsInError Method System.Data.DataColumn[] GetColumnsInError()
GetHashCode Method int GetHashCode()
GetParentRow Method System.Data.DataRow GetParentRow(string relatio...
GetParentRows Method System.Data.DataRow[] GetParentRows(string rela...
GetType Method type GetType()
HasVersion Method bool HasVersion(System.Data.DataRowVersion vers...
IsNull Method bool IsNull(int columnIndex), bool IsNull(strin...
RejectChanges Method void RejectChanges()
SetAdded Method void SetAdded()
SetColumnError Method void SetColumnError(int columnIndex, string err...
SetModified Method void SetModified()
SetParentRow Method void SetParentRow(System.Data.DataRow parentRow...
ToString Method string ToString()
Item ParameterizedProperty System.Object Item(int columnIndex) {get;set;},...
data_provider_id Property byte data_provider_id {get;set;}
id Property int id {get;set;}
is_active Property uint64 is_active {get;set;}
SSDD
[解决]尽管wchiquito的回答并不是一个完整的解决方案,但它仍然朝着正确的方向推动我。 DataTable.Load()
中的类型转换确实有些破坏,因此您需要在调用Load()
之前向DataTable添加基本架构。以下可能并不完美,但它对我有用:
private static void TranslateSchema(
DataTable dataTable,
MySqlDataReader mysqlDataReader)
{
string columnName;
Type columnType;
mysqlDataReader.Read();
for (int i = 0; i < mysqlDataReader.FieldCount; i++)
{
columnName = mysqlDataReader.GetName(i);
columnType = mysqlDataReader.GetFieldType(i);
dataTable.Columns.Add(columnName, columnType);
}
}
bit(1)
仍然成为UInt64
,但我可以忍受。
答案 0 :(得分:1)
使用什么版本的Connector / Net?对于版本6.9.7,我无法重现该问题。
MySQL的:
CREATE TABLE `table` (
`id` TINYINT(1) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Auto-increment ID',
`data_provider_id` TINYINT(1) UNSIGNED NOT NULL COMMENT 'Data provider ID',
`is_active` BIT(1) NOT NULL DEFAULT b'1' COMMENT '0 = retired source',
`id_temp` INT(1) UNSIGNED DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `DATA_PROVIDER_ID` (`data_provider_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
C#:
...
DataTable schema = dr.GetSchemaTable();
...
结果:
`id` -> System.Byte
`data_provider_id` -> System.Byte
`is_active` -> System.UInt64
`id_temp` -> System.UInt32
...
DataTable table = mysqlConnection.GetSchema("DataTypes");
...
结果:
TypeName = BIT
...
CreateFormat = BIT
...
DataType = System.UInt64
...
============================
TypeName = TINY INT
...
CreateFormat = TINYINT UNSIGNED
...
DataType = System.Byte
...
============================
TypeName = INT
...
CreateFormat = INT UNSIGNED
...
DataType = System.UInt32
...