何年も経って、はっきりさせておきます:
Joshの回答は、文字列が空であるかどうかをテストするための便利な単純化を示しています(PowerShellの暗黙的なブール値への変換[1]に依存しています)が、Tommy(OP)の問題とは関係ありません。
代わりに、エラーメッセージ
「パラメーター値を ResultPropertyValueCollection から文字列に変換できませんでした。」
は、文字列値またはの$objDbCmd.Parameters["@telephone"].Value
いずれかを期待するため、問題の原因が null以外のケースであることを意味しますが、タイプは 、つまり値のコレクションです。[DBNull]::Value
$objUser.Telephone
[ResultPropertyValueCollection]
したがって、null 以外の場合、文字列値を割り当てる必要があり、これはコレクションから派生する必要があります。1 つのオプションは、最初のコレクション要素の値を取得することです。別のオプションは、すべての値をセパレーターで結合して単一の文字列を形成すること[string]::Join(';', $objUser.Telephone)
です。 )、単純に. [2]"$($objUser.Telephone)"
型指定されたメソッド パラメーター[string]:IsNullOrEmpty()
に値を渡すときに、PowerShell が暗黙的にコレクションを文字列化する方法により、型の不一致にもかかわらず、空のコレクションの検出が実際に機能しました。[2][string]
同様に、暗黙的なブール値への変換を使用すると、コレクションでも期待どおりに機能します。空のコレクションは に評価され$false
、空でないコレクションは$true
(少なくとも 2 つの要素があるか、単独の要素のみと見なされる限り) に評価されます$true
[1]。 )
したがって、1 つの解決策は、最初の電話番号エントリを使用することです。
$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 の自動からブール値への変換の包括的な概要については、この回答の下部のセクションを参照してください。
[2]コレクションを文字列に暗黙的に変換する場合、PowerShell はデフォルトで、コレクションの文字列化された要素を区切り文字として 1 つのスペースで結合します。セパレーターを自動変数でオーバーライドできますが$OFS
、実際にはめったに行われません。たとえば、配列'foo', 'bar'
は に変換され'foo bar'
ます。この変換は、コレクションのメソッドを明示的に呼び出した場合には適用されませんが、展開可能な (補間) 文字列内では適用されることに注意してください。.ToString()
"$array"