2011-11-09 40 views
5
數據

有沒有人發現,查詢數據(使用的LINQ to 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-sql嗎?一般來說,它並不是爲此而設計的。即使你//做一些事情會去批,這將是一個字段的更新,你仍然會得到的SubmitChanges後發送到您的數據庫100個單獨的更新語句。我的建議是在你的情況下,使用存儲過程(和我的方式一個LINQ-2-SQL風扇) – 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查詢,當所示的方法將導致N + 1個查詢。

+0

相信我在我的情況,我需要N + 1個查詢的形式給出 – jlp

+1

大:我做了我的一天好事:-) – Steven

+2

當你想上的所有記錄的操作是非常有用的(例如,您添加了一個新列,並且在生產中您希望填充足夠的值)。然後,您不希望進行單個查詢,以獲取所有數據,因爲數量龐大可能會超時。因此,您可以批量查詢,並在更多步驟中進行更新,但不會超時:) – Vlad

3

這有什麼錯TakeSkip?這些是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個重載。

相關問題