2010-12-16 82 views
0

我正在查看一些用於分頁表的linq to SQL代碼。其中,它需要返回記錄的子集和數據庫中的記錄總數。代碼如下所示:Linq to sql - 返回記錄子集和記錄總數的最佳方式

var query = (from p in MyTable select new {p.HostCable, p.PatchingSet}); 
int total = query.ToList().Count; 
query = query.Skip(5).Take(10); 

我想挖一點到時這個執行,我看到2個查詢發生什麼情況 - 一個來從數據庫中的所有行,一個得到該子集。不用說,獲取所有記錄的性能影響並不好。我猜「ToList」強制查詢被執行,然後Count方法針對整個List運行。

在重新分解的聲明更有效率 - 這是我的改進版本:

int total = MyTable.Count(); 
var query = (from p in MyTable select new {p.HostCable, p.PatchingSet}).Skip(5).Take(10); 

這導致SQL命中的「選擇計數。」然後一個SQL命中爲實際選擇記錄。

這是最佳的,有沒有更好的解決方案?

謝謝!

回答

1
int total = query.Count(); 

,而不是選擇的一切,然後在內存中執行對象的數量,這將通過一個查詢進行計數,就回到這個數字應該是快了很多。

爲了迴應您的更新,我認爲您不會得到更好的方式。它最終歸結爲兩個查詢,一個是獲取記錄的總數,另一個是獲取記錄的子集。

+0

我同意。這將是最好的方法。計數(*)操作通常非常快(使用正確的索引)。 – Steven 2010-12-16 10:58:11

2

從我看到的情況來看,這在LINQ to SQL中是不可能的,沒有一點黑客攻擊。

我發現這種方法有效。此方法的快速總結:我將IQueryable對象轉換爲命令對象,並修改命令文本以在結果集中包含總計數。原始的LINQ to SQL轉換器SQL查詢使用ROW_NUMBER() OVER()語法來頁面行,我只是添加COUNT(*) OVER()以獲得總數。

將此方法添加到您的DataContext類。

public IEnumerable<TWithTotal> ExecutePagedQuery<T, TWithTotal>(IQueryable<T> query, int pageSize, int pageNumber, out int count) 
    where TWithTotal : IWithTotal 
{ 
    var cmd = this.GetCommand(query.Skip(pageSize * pageNumber).Take(pageSize)); 
    var commandText = cmd.CommandText.Replace("SELECT ROW_NUMBER() OVER", "SELECT COUNT(*) OVER() AS TOTALROWS, ROW_NUMBER() OVER"); 
    commandText = "SELECT TOTALROWS AS TotalCount," + commandText.Remove(0, 6); 
    cmd.CommandText = commandText; 

    var reader = cmd.ExecuteReader(); 

    var list = this.Translate<TWithTotal>(reader).ToList(); 

    if (list.Count > 0) 
     count = list[0].TotalCount; 
    else 
     count = 0; 

    return list; 
} 

你必須創建一個包含實現IWithTotal接口原始對象的所有屬性的新類。

更新:您不能在LINQ to SQL中混合使用映射和未映射的列。

public interface IWithTotal 
{ 
    int TotalCount { get; set; } 
} 

public class Project : IWithTotal 
{ 
    public int TotalCount { get; set; } 
    public int ProjectID { get; set; } 
    public string Name { get; set; } 
} 

DataContext.Translate有一定的要求,所以要確保,如果你有任何問題,你的查詢是否滿足這些需求。

根據查詢的複雜程度,您應該能夠看到性能提高。以下是我對計數查詢進行的測試,分頁選擇查詢以及帶查詢計數的分頁選擇。百分比是相對於批次的查詢成本。

Count - 6% 
Select with paging - 47% 
Select with paging + Count - 48%