Asp.Net MVC - LazyList Роба Конери - Счет () или Счет - PullRequest
2 голосов
/ 17 февраля 2009

Я пытаюсь создать 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; }
}

и я передаю заказчику. Заказы после загрузки клиенту. Теперь журнал, который я пытаюсь сделать, выглядит примерно так:

<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 для простого подсчета займет так много времени? Кажется, что он пытается перебрать список при получении простого подсчета.

Ответы [ 2 ]

3 голосов
/ 17 февраля 2009

LazyList загружает все данные при первом использовании, поэтому вы загружаете все заказы в списке при вызове Count. Получение всех данных из базы данных, создание экземпляров объектов и т. Д. Когда вы вызываете _repository.GetOrders (). ByCustomerID (custID) .Count (), он просто считает строки в базе данных и возвращает одно число.

1 голос
/ 22 апреля 2010

Проблема, с которой вы столкнулись, заключается в том, что LazyList заполняет весь список заказов из базы данных, чтобы вы могли их посчитать. Это большая работа, чтобы просто подсчитать.

Вы можете изменить метод Count в классе LazyList следующим образом:

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

Если список заказов еще не обработан, он вместо этого запросит IQueryable для Count. Вызывая .Count () в IQueryable, вы запрашиваете LINQ to SQL, чтобы просто получить количество результатов, это будет преобразовано в нечто вроде «SELECT COUNT (*) FROM Orders». Делать это намного эффективнее, чем увлажнять все результаты, а затем подсчитывать их, особенно если вас интересует только число!

...