Linq to sql - 返回记录子集和记录总数的最佳方式

Linq to sql - 返回记录子集和记录总数的最佳方式

问题描述:

我正在查看一些用于分页表的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命中为实际选择记录。

这是最佳的,有没有更好的解决方案?

谢谢!

int total = query.Count(); 

,而不是选择的一切,然后在内存中执行对象的数量,这将通过一个查询进行计数,就回到这个数字应该是快了很多。

为了回应您的更新,我认为您不会得到更好的方式。它最终归结为两个查询,一个是获取记录的总数,另一个是获取记录的子集。

+0

我同意。这将是最好的方法。计数(*)操作通常非常快(使用正确的索引)。 – Steven 2010-12-16 10:58:11

从我看到的情况来看,这在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%