2011-11-09 11 views
5
में डेटा लेने के लिए/कोडित विस्तार विधि है कि डेटा ( LINQ का उपयोग कर SQL के) बैचों में क्वेरी

किसी को भी पाया गया है? मैं IEnumerable एक्सटेंशन को देखा है लेकिन मैं कुछ मैं इस तरह इस्तेमाल कर सकते हैं के लिए देख रहा हूँ:IQueryable <T> विस्तार विधि बैचों

IQueryable<Order> orders = from i in db.Orders select i; 
foreach(var batch in orders.InBatches(100)) 
{ 
    //batch of 100 products 
    foreach(var order in batch) 
    { 
     //do something 
    } 
} 
+1

क्या आप वाकई बैचों के लिए Linq-2-एसक्यूएल का उपयोग करना चाहते हैं। सामान्यतः, यह ऐसा करने के लिए डिज़ाइन नहीं किया गया है। यहां तक ​​कि यदि आपका // कुछ बैच में जाता है और यह एक फ़ील्ड का अपडेट होगा, फिर भी आपको सबमिचेंज के बाद आपके डीबी को भेजे गए 100 व्यक्तिगत अपडेट स्टेटमेंट मिलेंगे। मेरे सलाह अपने मामले एक संग्रहीत प्रक्रिया का उपयोग करने के लिए है (और मैं जिस तरह से एक Linq-2-एसक्यूएल प्रशंसक हूँ) – Pleun

+0

धन्यवाद, लेकिन मेरे कोड केवल क्वेरी, – jlp

उत्तर

9

इस आप क्या कर सकते है:

public static IEnumerable<IQueryable<T>> InBatches(
    this IQueryable<T> collection, int size) 
{ 
    int totalSize = collection.Count(); 

    for (int start = 0; start < totalSize; start += size) 
    { 
     yield return collection.Skip(start).Take(size); 
    } 
} 

इस विस्तार विधि आप बदले IQueryables पर अतिरिक्त फिल्टर करने के लिए अनुमति देता है। हालांकि, उपयोगिता काफी सीमित है। मैं इसके लिए किसी भी अच्छे परिदृश्य के बारे में नहीं सोच सकता :-)। अधिकांश में परिदृश्य के तुम सिर्फ परिणाम स्ट्रीम और वापस लौटने वाले एक IEnumerable<IEnumerable<T>> ठीक करना होगा चाहते हैं, और, और भी बेहतर है के बाद से इस एक एकल SQL क्वेरी में परिणाम होगा, जबकि दिखाया दृष्टिकोण एन 1 प्रश्नों का परिणाम देगा।

+0

मुझे मेरे परिदृश्य में विश्वास है कि मैं + 1 प्रश्नों aproach n जरूरत – jlp

+1

महान: मैं दिन के लिए मेरे अच्छे काम किया :-) – Steven

+2

यह वास्तव में उपयोगी होता है जब आप सभी रिकॉर्ड पर कार्रवाई बनाना चाहते एक तालिका (उदाहरण के लिए, आपने एक नया कॉलम जोड़ा, और उत्पादन में आप पर्याप्त मूल्य के साथ पॉप्युलेट करना चाहते हैं)। फिर आप सभी डेटा प्राप्त करने के लिए एक प्रश्न नहीं बनाना चाहते हैं, क्योंकि यह बड़ी मात्रा के कारण समय समाप्त हो सकता है। इसलिए आप बैचों में प्रश्न पूछते हैं, और अपने अपडेट को और चरणों में बनाते हैं, लेकिन टाइमआउट के बिना :) – Vlad

3

क्या Take और Skip साथ गलत क्या है? ये LINQ ऑपरेटरों को IEnumerable<T> या IQueryable<T> (और उनके गैर-जेनेरिक समकक्ष) से ​​बैच प्राप्त करने के लिए हैं।

+1

कुछ भी नहीं अपडेट नहीं करता सिवाय मैं पहली बार रिकॉर्ड की संख्या और उसके बाद पाश बनाने की जरूरत है । मैं विस्तार विधि के लिए कहा मैं पुन: उपयोग कर सकते हैं कि – jlp

1

आप खुद को बैचों के बारे में परवाह नहीं है और तुम सिर्फ आकार या लेन-देन के प्रयोजनों के लिए कनेक्शन को तोड़ने के लिए आप क्या कर सकते हैं निम्नलिखित:

public static IEnumerable<T> InBatches<T>(this IQueryable<T> collection, int batchSize) 
{ 
    int start = 0; 
    int records = 0; 
    IQueryable<T> batch; 

    // For the first batch 
    start -= batchSize; 

    do { 
     records = 0; 
     start += batchSize; 
     batch = collection.Skip(start).Take(batchSize); 

     foreach (T item in batch) { 

      records += 1; 
      yield return item; 
     } 

    } while (records == batchSize); 
} 
0

MoreLINQ जो एक शानदार पुस्तकालय है एक बैच के साथ आता है विधि जो वास्तव में करता है।

https://github.com/morelinq/MoreLINQ

बैच

बैचों आकार बाल्टी में स्रोत अनुक्रम।

इस विधि 2 भार के है।

संबंधित मुद्दे