PowerShell ForEach / Rohrleitungen Verwirrung
Ich bin mit dem TFS PowerTools-Cmdlets in der PowerShell, um zu versuchen, einige Informationen über die Änderungen und die zugehörigen WorkItems von meinem server. Ich habe gekocht, das problem zu Verhalten, die ich nicht verstehe und ich hoffe, es ist nicht spezifische TFS (also jemand da draußen möglicherweise in der Lage zu erklären, das problem für mich 🙂 )
Hier ist der einzige Befehl, den ich bekommen kann, um zu arbeiten:
Bekommen-TfsItemHistory C:\myDir -recurse -stopafter 5 | % { Write-Host $_.WorkItems[0]["Titel"] }
Tut es was ich erwarte - Get-TfsItemHistory gibt eine Liste von 5 Änderungen, und es Pfeifen die zu einer foreach-druckt den Titel des ersten verbundenen Arbeitsaufgaben. Also, was ist mein problem? Ich bin versucht zu schreiben, ein großes Skript, und ich bevorzuge code Dinge zu schauen, mehr wie ein C# - Programm (powershell-syntax macht mich Weinen). Immer wenn ich versuche das oben geschrieben andere Weise, die WorkItems Sammlung ist null.
Die folgenden Befehle (die ich interpretieren, um logisch äquivalent) funktionieren nicht (Die WorkItems Sammlung ist null):
$items = Get-TfsItemHistory C:\myDir -recurse -stopafter 5 $items | ForEach-Object { Write-Host $_.WorkItems[0]["Titel"] }
Den einen würde ich wirklich lieber:
$items = Get-TfsItemHistory C:\myDir -recurse -stopafter 5 foreach ($item in $items) { $item.WorkItems[0]["Titel"] # mache viele andere Sachen }
Las ich einen Artikel über den Unterschied zwischen der 'foreach' - operator und die ForEach-Object-Cmdlet, das scheint aber eher ein performance-Debatte. Dies erscheint wirklich ein Problem sein, etwa wenn die Rohrleitung verwendet wird.
Ich bin mir nicht sicher, warum alle drei Ansätze nicht funktionieren. Jede Einsicht wird sehr geschätzt.
- Ich bin mir nicht sicher, was das problem ist, aber es ist bestimmt spezifisch für die TFS Cmdlets (Sie sind ziemlich schrecklich, imo). Es scheint, dass das cmdlet Tat, lazy loading, und sobald die pipeline endet, werden die Daten-Rahmen ist verschwunden und es ist zu spät, um die Daten zu laden, aber das design des cmdlets ist so verworren, dass ich konnte nicht verfolgen, die weit in den Reflektor.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist in der Tat verwirrend. Jetzt ein work-around ist, greifen die Elemente so:
Diese greift auf die WorkItems Sammlung, die zu verursachen scheint diese Eigenschaft aufgefüllt werden (ich weiß - WTF?). Ich Neige dazu, verwenden Sie
@()
erzeugen ein array, in Fällen, in denen möchte ich die foreach-Schlüsselwort. Die Sache mit dem Schlüsselwort "foreach" ist, dass es die Iteration eines skalaren Wert einschließlich $null. So ist das, wenn die Abfrage nichts zurückgibt,$items
zugewiesen bekommt $null, und die foreach iteriert die Schleife einmal mit$item
auf null gesetzt. Jetzt PowerShell in der Regel behandelt mit null sehr schön. Allerdings, wenn Sie die hand, die Wert zurück, auf den .NET Framework, ist es in der Regel nicht so nachsichtig. Die@()
garantieren ein array mit entweder 0, 1 oder N Elemente. Wenn es 0 ist dann die foreach-Schleife wird nicht ausgeführt, seinen Körper auf alle.BTW deine Letzte Ansatz -
foreach ($item in $items) { ... }
- sollte gut funktionieren.