我需要用pwsh 7从mysql数据库中读取数据。在powershell 5上,它工作得很好,但是pwsh 7不工作,并在查询带有“时间戳”数据的表时收到一条错误消息:
“格式-默认值:无法将'MySql.Data.Types.MySqlDateTime‘类型的对象强制转换为’System.IFormattable‘。”
[void][system.reflection.Assembly]::LoadWithPartialName("MySql.Data")
$connStr = "server=" + $MySQLHost + ";port=" + $MySQLPort + ";uid=" + $user + ";pwd=" + $pass + ";database=" + $MYSQLDatabase + ";Pooling=FALSE;Allow Zero Datetime=true;Allow User Variables=True;Connect Timeout=60"
$conn = New-Object MySql.Data.MySqlClient.MySqlConnection($connStr)
$conn.Open()
New-Object MySql.Data.MySqlClient.MySqlCommand("USE $database", $conn)
$query = "select Name, InputDate from ENVIRONMENT"
$cmd = New-Object MySql.Data.MySqlClient.MySqlCommand($query, $conn)
$dataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($cmd)
$dataSet = New-Object System.Data.DataSet
$dataAdapter.Fill($dataSet, "data")
$cmd.Dispose()
$dataSet.Tables["data"] 所以我可以看到,在"$dataAdapter.Fill($dataSet,“data”)之后,数据是从mysql收集的,因为它返回行数。但是在“$dataSet.Tables”数据“它返回错误”之后。
在powershell 5中,它工作得很好。
有什么帮助:-)?
谢谢
发布于 2022-08-03 16:40:21
如果您的代码在Windows PowerShell中工作,但在PowerShell (核心) 7+中不起作用,那么我鼓励您在PowerShell GitHub回购中报告一个问题。
但是,您应该首先确保从.NET (核心)程序集(MySql.Data)加载NuGet包的-appropriate版本,因为[System.Reflection.Assembly]::LoadWithPartialName("MySql.Data")可能正在从GAC (Global )加载一个旧的、仅限于.NET框架的版本,等效的(更可取的)表单Add-Type -AssemblyName MySql.Data也是如此。
不幸的是,使用NuGet包在PowerShell版本7.2.x中不受很好的支持:
关于错误和潜在的慢速解决办法的一些想法:
MySql.Data.Types.MySqlDateTime确实没有实现System.IFormattable接口。我不清楚为什么这个角色会被尝试,或者--如果这个尝试是故意的--为什么这个异常没有被捕获。
当PowerShell字符串对象时,它检查它们是否实现了IFormattable,以便可以请求区域性不变的字符串表示。可以想象,这个错误与错误地相信MySqlDateTime来实现这个接口有关。
MySqlDateTime确实有一个显式转换算子到.NET的[datetime] (System.DateTime)类型,您应该可以通过[datetime]强制转换从PowerShell使用该类型。
因此,以下方法可以作为一种解决办法:
MySqlDateTime-typed属性(列)替换为在Select-Object和计算性质的帮助下显式地将值转换为[datetime]的属性。注意:下面是一个模拟您的MySQL数据类型的简化的、自成一体的示例;为了简单起见,使用[string]类型代替[MySql.Data.Types.MySqlDateTime]来修改感兴趣的列,并相应地使用显式的[datetime]强制转换。
# These sample rows simulate the following:
# $rows = $dataSet.Tables["data"]
$rows = @(
[pscustomobject] @{
foo = 1;
bar = '1970/01/01'
},
[pscustomobject] @{
foo = 2;
bar = '1970/01/02'
}
)
# Get the first row, so the data types of its properties (columns)
# can be analyzed.
# (I assume there's a way to do this directly via a table object,
# and its column definitions, but I'm not familiar with the MySQL .NET API.)
$firstRow = $rows | Select-Object -First 1
# Construct an array of property names / calculated properties to pass
# to Select-Object below.
$propArray = foreach ($prop in $firstRow.psobject.Properties) {
if ($prop.Value -is [string]) { # Substitute [MySql.Data.Types.MySqlDateTime] here.
@{
Name = $prop.Name
Expression = [scriptblock]::Create("[datetime] `$_.$($prop.Name)")
}
}
else {
$prop.Name
}
}
# Now output all rows with the [MySqlDateTime] columns (properties)
# converted to [datetime].
$rows | Select-Object $propArrayhttps://stackoverflow.com/questions/73182595
复制相似问题