多年后,让我澄清一下:
Josh's answer 展示了一种有助于测试空字符串的简化方法(依赖于 PowerShell 的 implicit 到布尔转换[1]),但它与 Tommy 的 ( OP的)问题。
相反,错误信息
“将参数值从 ResultPropertyValueCollection 转换为字符串失败。”
暗示 是 non-null 情况导致了问题, 因为$objDbCmd.Parameters["@telephone"].Value 需要 string 值或 @987654324 @,而$objUser.Telephone 是[ResultPropertyValueCollection] 类型,即值的集合。
因此,在非空情况下,必须分配一个字符串值,该值必须从集合中派生;一种选择是采用 first 集合元素的值,另一种方法是使用分隔符连接所有值以形成单个字符串,例如使用 [string]::Join(';', $objUser.Telephone) 或者,如果使用 空格是可以接受的(对于多个电话号码不是一个好主意),只需使用"$($objUser.Telephone)"。[2]
尽管类型不匹配,但通过 [string]:IsNullOrEmpty() 检测空集合实际上有效,因为 PowerShell 在将值传递给 [string] 类型化方法参数时如何隐式字符串化集合。[2]
类似地,使用 隐式 到布尔转换也可以按预期对集合进行:空集合评估为 $false,非空集合评估为 $true(只要有至少两个元素或唯一的元素本身将被视为$true[1])
因此,一种解决方案是使用 first 电话号码条目:
$objDbCmd.Parameters["@telephone"].Value = if ($objUser.Telephone) {
$objUser.Telephone[0].ToString() # use first entry
} else {
[DBNull]::Value
}
注意:如果$objUser.Telephone[0]直接返回[string],可以省略.ToString()调用。
在 PowerShell v7+ 中,您也可以通过三元条件来缩短语句:
$objDbCmd.Parameters["@telephone"].Value =
$objUser.Telephone ? $objUser.Telephone[0].ToString() : [DBNull]::Value
[1] 有关 PowerShell 自动到布尔转换的全面总结,请参阅this answer 的底部部分。
[2] 当隐式将集合转换为字符串时,PowerShell默认以单个空格作为分隔符连接集合的字符串化元素;您可以使用自动$OFS 变量覆盖分隔符,但这在实践中很少这样做;例如,数组'foo', 'bar' 转换为'foo bar';请注意,当您调用集合的.ToString() 方法显式 时,此转换不适用,但它确实适用于可扩展(插值)字符串,例如"$array"。