【问题标题】:Asp.Net MVC - Rob Conery's LazyList - Count() or CountAsp.Net MVC - Rob Conery 的 LazyList - Count() 或 Count
【发布时间】:2009-02-17 20:38:12
【问题描述】:

我正在尝试为客户的订单日志创建一个 html 表。客户被定义为(我遗漏了很多东西):

public class Customer
{
    public LazyList<Order> Orders { get; set; }
}

在获取客户时设置 LazyList:

public Customer GetCustomer(int custID)
{
    Customer c = ...
    c.Orders = new LazyList<Order>(_repository.GetOrders().ByOrderID(custID));
    return c;
}

订单日志模型:

public class OrderLogTableModel
{
    public OrderLogTableModel(LazyList<Order> orders)
    {
        Orders = orders;
        Page = 0;
        PageSize = 25;
    }

    public LazyList<Order> Orders { get; set; }
    public int Page { get; set; }
    public int PageSize { get; set; }
}

我在加载客户后传入 customer.Orders。现在我正在尝试制作的日志看起来像:

<table>
<tbody>
<% 
    int rowCount = ViewData.Model.Orders.Count();
    int innerRows = rowCount - (ViewData.Model.Page * ViewData.Model.PageSize);
    foreach (Order order in ViewData.Model.Orders.OrderByDescending(x => x.StartDateTime)
                            .Take(innerRows).OrderBy(x => x.StartDateTime)
                            .Take(ViewData.Model.PageSize))
    {
        %>
        <tr>
            <td>
                <%= order.ID %>
            </td>
        </tr>
        <%
    }
%>
</tbody>
</table>

效果很好。但问题是评估 ViewData.Model.Orders.Count() 实际上需要大约 10 分钟。

我已经尝试使用 ViewData.Model.Orders.Count 属性,结果是一样的 - 需要永远。

我也尝试过直接从视图调用 _repository.GetOrders().ByCustomerID(custID).Count() 并在几毫秒内完美执行。

任何人都知道为什么使用 LazyList 进行简单计数需要这么长时间吗?在获得简单计数时,它似乎试图遍历列表。

【问题讨论】:

    标签: c# asp.net asp.net-mvc linq-to-sql lazy-loading


    【解决方案1】:

    LazyList 在首次使用时加载所有数据,因此您在 Count 调用中加载列表中的所有订单。从 db 中获取所有数据,实例化对象等。当您调用 _repository.GetOrders().ByCustomerID(custID).Count() 时,它只计算数据库中的行数并返回一个数字。

    【讨论】:

      【解决方案2】:

      您遇到的问题是LazyList<T> 正在从数据库中填充整个订单列表,以便您可以计算它们。做一个简单的计数就需要做很多工作。

      您可以将 LazyList 类的 Count 方法修改为以下内容:

      public int Count 
      {
          get 
          { 
              if(inner == null)
                  return query.Count;
              else
                  return inner.Count;
          }
      }
      

      如果订单列表尚未完成,它将改为向 IQueryable 询问计数。通过在 IQueryable 上调用 .Count() 您要求 LINQ to SQL 仅获取结果数,这将被转换为类似“SELECT COUNT(*) FROM Orders”的内容。这样做比对所有结果进行水合然后计算它们更有效,尤其是如果您只对数字感兴趣!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-01-07
        • 2012-05-15
        • 1970-01-01
        • 1970-01-01
        • 2011-05-01
        • 2011-12-26
        • 2011-12-06
        相关资源
        最近更新 更多