使用1个连接分配3个子查询,使用2个连接分配2个查询

时间:2016-11-30 16:40:28

标签: sql sql-server entity-framework asp.net-mvc-5 entity-framework-6

我一直在做很多关于Paging的研究,我被困在两种方法之间。使用这两种方法,我将使用PagedList.MVC来显示我的页面,但问题在于如何将数据传递给PagedList以及我的两种方法中的哪一种更有效。

我发现的最好的例子如下:

public static PagedList<Customer> GetPagedCustomers(int skip, int take)
{
  using (var context = new AdventureWorksLTEntities())
  {
    var query = context.Customers.Include("SalesOrderHeaders")
      .Where(c => c.SalesOrderHeaders.Any())
      .OrderBy(c => c.CompanyName + c.LastName + c.FirstName);
    var customerCount = query.Count();
    var customers = query.Skip(skip).Take(take).ToList();

    return new PagedList<Customer>
    {
      Entities = customers,
      HasNext = (skip + 10 < customerCount),
      HasPrevious = (skip > 0)
    };
  }
}

Reference to original article

如果仔细查看该代码,实际上会发生2个查询,一个接一个。第一个是var customerCount = query.Count();,第二个是var customers = query.Skip(skip).Take(take).ToList();

虽然我喜欢上面的查询方法非常轻,并且一次只能检索10条记录,但我不喜欢它会两次访问数据库。

我的第二种方法是更自定义,并且涉及直接在服务器上运行查询以及分页。现在这个查询正在与Dapper一起运行,但是如果这里的回复与我同意,我会按照我的方式工作。

SELECT *             
FROM (
    SELECT
        *,1 as SplitOn,
        (ROW_NUMBER() OVER(ORDER BY @SortColumn )) AS RowNum, COUNT(*) over() as TotalRows
            FROM ( 
                @CustomQuery
            ) AS FirstQuery
    ) AS TEMP 
WHERE RowNum BETWEEN 1 + ((@Page - 1) * @PageSize) AND @Page * @PageSize

要用dapper解析它,代码看起来像这样

var simpleQuery = "Select * FROM Customers";
var finalQuery = string.Format(pageQuery, simpleQuery)
var obj = myWrapper();

using (var oConn = CreateConnection(ConnectionString))
{
    TotalPages totalRows = null;
    var list = oConn.Query<T, TotalPages, T>(finalQuery, (e, t) =>
    {
        totalRows = t;
        if (mapAction != null) mapAction(e);
        return e;
    }, param, splitOn: "SplitOn");
}

obj.RowsFound = (IEnumerable<dynamic>)list;
obj.TotalRows = totalRows == null ? 0 : totalRows.TotalRows;

以上几项内容正在传递,例如类型<T>object paramAction<T> mapAction,这些事情对我的问题并不重要,因为问题是:< / p>

在第一个例子中,我要查询两次。在第二个例子中,我查询了一次,但我基本上做了1个查询和2个子查询。对于具有服务器百万条记录的表而言,这种方法更有效,并且由于它有大量流量而经常受到攻击。我的目标是理解在一个连接中在服务器上查询基本上3次更好。或者通过2个与数据库的单独连接进行2次查询。

编辑:

我更多地考虑了这一点,第一个例子实际上也是2个子查询。由于在调用ToList()方法之前查询的性质没有执行,它只会附加查询并构建它。

老实说,我真的相信第二种方法会更好,但我希望得到一些保证。

0 个答案:

没有答案