從我看到的情況來看,這在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%
我同意。這將是最好的方法。計數(*)操作通常非常快(使用正確的索引)。 – Steven 2010-12-16 10:58:11