Domanda

Sono perplesso da questo semplice problema di dati.

sto utilizzando Entity Framework e avere un database di prodotti. La mia pagina dei risultati restituisce un elenco impaginato di questi prodotti. In questo momento i miei risultati sono ordinati per il numero di vendite di ogni prodotto, quindi il mio codice simile a questo:

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

Questo restituisce un dataset IQueryable dei miei soggetti, in ordine di numero di vendite.

Voglio che la mia pagina dei risultati per mostrare rango di ciascun prodotto (nel set di dati). I miei risultati dovrebbe essere simile a questo:

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

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

Mi aspetto che voglio solo aggiungere una colonna nei miei risultati utilizzando la variabile SQL ROW_NUMBER ... ma non so come aggiungere questa colonna per il mio risultato datatable.

La mia pagina risultante contiene un ciclo foreach, ma dal momento che sto utilizzando un set impaginato sto cercando di indovinare usando quel numero di falsificare un numero classifica non sarebbe l'approccio migliore.

Quindi la mia domanda è: come faccio ad aggiungere una colonna ROW_NUMBER ai miei risultati delle query in questo caso?

Nessuna soluzione corretta

Altri suggerimenti

Utilizza il sovraccarico indicizzato di 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 });

In realtà utilizzando OrderBy e quindi saltare + Prendere genera ROW_NUMBER a EF 4.5 (è possibile controllare con SQL Profiler).

ero alla ricerca di un modo per fare la stessa cosa si sta chiedendo e sono stato in grado di ottenere quello che mi serve attraverso una semplificazione della risposta di Craig:

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

Tra l'altro, l'SQL generato utilizza ROW_NUMBER> inizio e TOP rowsPerPage.

Ecco una risposta prolissa. In primo luogo creare una classe per ospitare la coppia / numero di voce in questo modo:

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

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

Avanti viene un'astrazione intorno una pagina di elementi (numerati e non):

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();
    }
}

Una volta che avete che è possibile "Impagina" una particolare collezione interrogabile tramite questo:

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 infine un metodo di estensione piacevole per coprire il brutto:

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

Il che significa che ora si può fare questo:

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);
}

Prova questo

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
}

Fino a quando la lista rimane nello stesso ordine, che dovrebbe avvenire a meno che il numero di vendita cambia. Potresti essere in grado di ottenere un conteggio accurato;

C'è anche questo modo di farlo.

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);

In questo modo l'indice di partenza per la pagina, più ti dà un piccolo set di vendita per visualizzare nella pagina. Basta avviare il conteggio sul tuo sito web startIndex.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top