Pergunta

Estou perplexo por este problema de dados mais fácil.

Eu estou usando o Entity Framework e têm um banco de dados de produtos. Minha página de resultados retorna uma lista paginado destes produtos. Agora os meus resultados são ordenados pelo número de vendas de cada produto, então meus olhares código como este:

return Products.OrderByDescending(u => u.Sales.Count());

Isso retorna um conjunto de dados IQueryable dos meus entidades, classificadas pelo número de vendas.

Eu quero a minha página de resultados para mostrar a classificação de cada produto (no conjunto de dados). Meus resultados deve ficar assim:

Page #1
1. Bananas
2. Apples
3. Coffee

Page #2
4. Cookies
5. Ice Cream
6. Lettuce

Eu estou esperando que eu só quero adicionar uma coluna em meus resultados usando a variável SQL ROW_NUMBER ... mas eu não sei como adicionar esta coluna para os meus resultados DataTable.

A minha página resultante contém um loop foreach, mas desde que eu estou usando um conjunto paginado Eu estou supondo usando esse número de falsificar um número ranking não seria a melhor abordagem.

Assim, a minha pergunta é: como faço para adicionar uma coluna ROW_NUMBER aos meus resultados da consulta neste caso?

Nenhuma solução correta

Outras dicas

Use a indexada sobrecarga de Select :

var start = page * rowsPerPage;
Products.OrderByDescending(u => u.Sales.Count())
    .Skip(start)
    .Take(rowsPerPage)
    .AsEnumerable()
    .Select((u, index) => new { Product = u, Index = index + start });

Na verdade usando OrderBy e depois Ir + Faça gera ROW_NUMBER em EF 4.5 (você pode verificar com o SQL Profiler).

Eu estava procurando uma maneira de fazer a mesma coisa que você está pedindo e eu era capaz de conseguir o que eu preciso através de uma simplificação da resposta de Craig:

var start = page * rowsPerPage;
Products.OrderByDescending(u => u.Sales.Count())
    .Skip(start)
    .Take(rowsPerPage)
    .ToList();

A propósito, o SQL gerado usa ROW_NUMBER> começar e TOP rowsPerPage.

Aqui está uma resposta prolixo. Primeiro crie uma classe para abrigar o número par / artigo assim:

public class NumberedItem<T>
{
    public readonly int Number;
    public readonly T Item;

    public NumberedItem(int number, T item)
    {
        Item = item;
        Number = number;
    }
}

Em seguida, vem uma abstração em torno de uma página de itens (numerados ou não):

class PageOf<T> : IEnumerable<T>
{
    private readonly int startsAt;
    private IEnumerable<T> items;

    public PageOf(int startsAt, IEnumerable<T> items)
    {
        this.startsAt = startsAt;
        this.items = items;
    }

    public IEnumerable<NumberedItem<T>> NumberedItems
    {
        get
        {
            int index = 0;
            foreach (var item in items)
                yield return new NumberedItem<T>(startsAt + index++, item);
            yield break;
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        foreach (var item in items)
            yield return item;
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

Uma vez que você tem que você pode "Paginate" uma coleção particular queryable usando este:

class PaginatedQueryable<T>
{
    private readonly int PageSize;
    private readonly IQueryable<T> Source;

    public PaginatedQueryable(int PageSize, IQueryable<T> Source)
    {
        this.PageSize = PageSize;
        this.Source = Source;
    }

    public PageOf<T> Page(int pageNum)
    {
        var start = (pageNum - 1) * PageSize;
        return new PageOf<T>(start + 1, Source.Skip(start).Take(PageSize));
    }
}

E, finalmente, um método de extensão agradável para cobrir o feio:

static class PaginationExtension
{
    public static PaginatedQueryable<T> InPagesOf<T>(this IQueryable<T> target, int PageSize)
    {
        return new PaginatedQueryable<T>(PageSize, target);
    }
}

que significa que você agora pode fazer isso:

var products = Products.OrderByDescending(u => u.Sales.Count()).InPagesOf(20).Page(1);

foreach (var product in products.NumberedItems)
{
    Console.WriteLine("{0} {1}", product.Number, product.Item);
}

Tente este

var x = Products.OrderByDecending(u => u.Sales.Count());
var y = x.ToList();

for(int i = 0; i < y.Count; i++) {
    int myNumber = i; // this is your order number
}

Enquanto as estadias de lista na mesma ordem, que deve acontecer a menos que o número de vendas mudanças. Você poderia ser capaz de obter uma contagem precisa;

Há também esta maneira de fazê-lo.

var page = 2;
var count = 10;
var startIndex = page * count;

var x = Products.OrderByDecending(u => u.Sales.Count());
var y = x.Skip(startIndex).Take(count);

Isto dá ao índice inicial para a página, além de que lhe dá um pequeno conjunto de vendas para exibição na página. Você acabou de começar a contagem em seu website em startIndex.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top