2010-10-24 21 views
7

मैं अपने सर्वर से परिवर्तन और संबंधित वर्कइटम के बारे में कुछ जानकारी प्राप्त करने के लिए PowerShell में TFS PowerTools Cmdlets का उपयोग कर रहा हूं। मैंने समस्या को हल करने के लिए समस्या को उबाल दिया है और मुझे उम्मीद है कि यह टीएफएस विशिष्ट नहीं है (इसलिए कोई व्यक्ति मुझे समस्या की व्याख्या करने में सक्षम हो सकता है :))पावरशेल फॉरएच/पाइपिंग भ्रम

यहां एकमात्र आदेश है जो मैं कर सकता हूं काम करने के लिए मिल:

 
Get-TfsItemHistory C:\myDir -recurse -stopafter 5 | % { Write-Host $_.WorkItems[0]["Title"] } 

यह मैं क्या उम्मीद करता है - Get-TfsItemHistory 5 changesets की सूची लौटाता है, और यह पाइप एक foreach कि पहली जुड़े WorkItem का शीर्षक बाहर प्रिंट करने के लिए उन। तो मेरी समस्या क्या है? मैं एक बड़ी लिपि लिखने की कोशिश कर रहा हूं, और मैं सी # प्रोग्राम की तरह दिखने के लिए चीजों को कोड करना पसंद करता हूं (पावरहेल सिंटैक्स मुझे रोता है)। जब भी मैं उपर्युक्त लिखित किसी भी अन्य तरीके से करने की कोशिश करता हूं, तो WorkItems संग्रह शून्य है।

निम्न कमांड (जो मैं तार्किक बराबर होने का व्याख्या) काम नहीं करते (WorkItems संग्रह रिक्त है):

 
$items = Get-TfsItemHistory C:\myDir -recurse -stopafter 5 
$items | ForEach-Object { Write-Host $_.WorkItems[0]["Title"] } 

एक मैं वास्तव में पसंद करेंगे:

 
$items = Get-TfsItemHistory C:\myDir -recurse -stopafter 5 
foreach ($item in $items) 
{ 
    $item.WorkItems[0]["Title"] 
    # do lots of other stuff 
} 

मैंने पढ़ा 'foreach' ऑपरेटर और फॉरएच-ऑब्जेक्ट सीएमडीलेट के बीच अंतर के बारे में एक लेख, लेकिन ऐसा लगता है कि यह एक प्रदर्शन बहस का अधिक है। यह वास्तव में एक मुद्दा है जब पाइपिंग का उपयोग किया जा रहा है।

मुझे यकीन नहीं है कि इन तीनों में से तीन दृष्टिकोण क्यों काम नहीं करते हैं। किसी भी अंतर्दृष्टि की सराहना की है।

+3

मुझे यकीन नहीं है कि समस्या क्या है, लेकिन यह निश्चित रूप से टीएफएस सीएमडीलेट्स के लिए विशिष्ट है (वे बल्कि भयानक, आईएमओ हैं)। ऐसा प्रतीत होता है कि cmdlet आलसी लोडिंग कर रहा था, और एक बार पाइपलाइन समाप्त होने के बाद, डेटा संदर्भ समाप्त हो गया है और डेटा लोड करने में बहुत देर हो चुकी है, लेकिन cmdlets का डिज़ाइन इतनी गड़बड़ है कि मैं इसे अब तक ट्रैक नहीं कर सकता । – Jaykul

उत्तर

8

यह वास्तव में भ्रमित है। अभी के लिए एक काम के आसपास इतना जैसी मदों हड़पने के लिए है:

$items = @(Get-TfsItemHistory . -r -Stopafter 25 | 
      Foreach {$_.WorkItems.Count > $null; $_}) 

यह WorkItems संग्रह जो पैदा करने के लिए इस संपत्ति से भरा जा रहा है तक पहुँचता है (मुझे पता है - WTF?)। मैं उन मामलों में सरणी उत्पन्न करने के लिए @() का उपयोग करता हूं जहां मैं foreach कीवर्ड का उपयोग करना चाहता हूं। Foreach कीवर्ड के साथ बात यह है कि यह $ null सहित एक स्केलर मूल्य फिर से शुरू होगा। तो यदि क्वेरी कुछ भी नहीं लौटाती है, तो $items $ null असाइन किया जाता है और फोरच $item के साथ एक बार लूप को फिर से चालू कर देगा। अब पावरशेल आम तौर पर बहुत अच्छी तरह से nulls के साथ सौदा करता है। हालांकि यदि आप उस मान को .NET Framework पर वापस सौंपते हैं, तो यह आमतौर पर क्षमा नहीं करता है। @() इसमें किसी भी 0, 1 या एन तत्वों के साथ एक सरणी की गारंटी देगा। यदि यह 0 है तो फ़ोरैच लूप अपने शरीर को निष्पादित नहीं करेगा।

बीटीडब्ल्यू आपका अंतिम दृष्टिकोण - foreach ($item in $items) { ... } - बस ठीक काम करना चाहिए।

+0

धन्यवाद, यह काम करता है। मैं ट्रैक पर वापस आ गया हूँ और मैं पागल नहीं हूँ! यह निश्चित रूप से अजीब है, यह जानना अच्छा होगा कि यह सब कुछ क्या है लेकिन इस बिंदु पर मैं एक और अधिक gremlins के लिए चाक तैयार करने के लिए तैयार हूँ। – Hexate