将字符串集合中的$_项传递到从Select Object调用的函数中



好的。。。所以我有一个System.Data.DataRow对象。我已经把列名放到了一个字符串集合中。然后我想将相应的值放入第二个集合中。

我确信我只是在做一些愚蠢的事情,但我一辈子都无法弄清楚这一点。取以下代码。。。

$cols = $drFrom.Table.Columns
$colNames = $cols | Where-Object { $_.ColumnName -ne "ROWID" } | Select-Object $_.ColumnName
Write-Host $colNames
$colValues = $colNames | Select-Object $drFrom.Item($_).ToString()

注意,Write-Host显示$colNames包含预期的列名,并在控制台中输出:

CLIENTID MESSAGE AMOUNT PAIDBY PAIDBYEMAIL ACTIVE

因此,这样做的目的是将$colNames管道传输到Select-Object中,并为每个列名从DataRow中获取值。但由于某种原因,当它在Select-Object中运行时,$_似乎返回为空,而不是已知存在于$colNames集合中的字符串值。当它运行第4行时,为了进行管道,它抛出了这个异常:

Exception getting "Item": "Exception calling "get_Item" with "1" argument(s): "'column' argument cannot be null.
Parameter name: column""
At D:MyScriptsMyScript.ps1:145 char:5
+     $colValues = $colNames | Select-Object $drFrom.Item($_).ToString( ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], GetValueInvocationException
+ FullyQualifiedErrorId : CatchFromBaseParameterizedPropertyAdapterGetValue

我还尝试过将迭代变量嵌入引号中,比如…

$colValues = $colNames | Select-Object $drFrom.Item("$_").ToString()

然后异常相应地改变,但仍然反映$_:的空值

Exception getting "Item": "Exception calling "get_Item" with "1" argument(s): "Column '' does not belong to table .""
+     $colValues = $colNames | Select-Object $drFrom.Item("$_").ToStrin ...

如何使迭代变量实际反映管道时$colNames中的字符串值?

要通过Select-Object动态定义属性,必须使用计算属性,该属性包括定义属性名称的哈希表和定义属性({ ... })的脚本块,在该脚本块中,您可以通过自动$_变量引用手头的管道输入对象。

但是,您不希望定义计算的属性,而是希望输出计算的。为此,您需要使用对ForEach-Object:的调用

$colNames = $cols | 
Where-Object ColumnName -ne ROWID |
ForEach-Object ColumnName
$colValues = $colNames |
ForEach-Object { $drFrom.Item($_).ToString() }

注意,对于Where-ObjectForEach-Object调用,第一个管道都使用简化的语法。

你说

我想将相应的值放入第二个集合中。

您有:

$cols = $drFrom.Table.Columns
$colNames = $cols | 
Where-Object { $_.ColumnName -ne "ROWID" } | 
Select-Object $_.ColumnName

这是有效的(但可以简化)。

现在有两件事你想做:

  • 选择列
  • 将列转换为字符串

单独做这些要简单得多。

首先选择您想要的属性:

$colValues = $drFrom |
Select-Object $colNames

现在您已经在PSCustomObject中拥有了所需的列。这很重要,因为我们可以使用隐藏的PSObject属性:

$colValues.PSObject.Properties.Name |
ForEach {$colValues.$_ = [string]$colValues.$_}

在这里,我已经从调用.ToString()切换到使用强制转换运算符[string],因为它处理$null时不会出错。

我想这会给你想要的。

您的列名计算可以简化为

$colNames = drFrom.Table.Columns.ColumnName | 
Where-Object {$_ -ne "ROWID"}

如果有任何可能drFrom是一个列表,那么:

$colNames = drFrom[0].Table.Columns.ColumnName | 
Where-Object {$_ -ne "ROWID"}

当您只想消除列时(似乎是这样),您可以简化为:

$colValues = $drFrom |
Select-Object * -ExcludeProperty "ROWID"

并将剩余属性转换为字符串:

$colValues.PSObject.Properties.Name |
ForEach {$colValues.$_ = [string]$colValues.$_}

当你写:

我想将相应的值放入第二个集合中。

不清楚您想要该集合的形式。上面我生成了一个具有命名属性的对象,因为我发现它在PowerShell中更有用。您提供的代码似乎试图提取字符串列表。如果这是你想要的,那么将上面的最后一行代码替换为:

$stringList = $colValues.PSObject.Properties.Name |
ForEach {[string]$colValues.$_}

我希望这能有所帮助。

相关内容

  • 没有找到相关文章

最新更新