3 votes

Ensemble complet de données plutôt que les 1000 premiers EF Core

J'essaie de retourner les 1000 premières lignes d'un tableau, mais en utilisant EF Core, j'obtiens le jeu de données complet avant l'exécution de .Take(1000).

API

[HttpGet("MyThing/{id}")]
public List<MyObj> ItemsReport(long id)
{
    response = new List<MyObj>();
    response = _reporting.GetNewEntries(id);
    return response;
}

Reporting

public virtual List<MyObj> GetNewEntries(long id)
{
    var newEntries = new List<MyObj>();

    var entries = _DbContext.ReportNewEntries
                            .OrderBy(a => long.Parse(a.Id))
                            .Where(a => long.Parse(a.Id) > id)
                            .Take(1000);

    newEntries.AddRange(entries);

    return newEntries;
}

DbContext

DbSet<MyObj> ReportNewEntries{ get; set; }

La demande que je souhaite formuler est à peu près la suivante :

SELECT TOP (1000) * 
FROM dbo.ReportNewEntries 
WHERE CONVERT(bigint, Id) > 0 
ORDER BY CONVERT(bigint, Id)

Ma requête actuelle, selon le profileur SQL est :

SELECT * FROM dbo.ReportNewEntries 

La table est monolithique, je veux donc accéder aux rangées 1000 à la fois. Avez-vous des suggestions sur l'erreur que je suis en train de commettre ?

0 votes

Le problème n'est pas clair, votre code ne renvoie déjà que 1000 lignes de la table.

0 votes

Essayé var entries = _DbContext.ReportNewEntries.Take(1000).OrderBy(a => long.Parse(a.Id)).Where(a => long.Parse(a.Id) > id); ?

0 votes

@AhmedYousif La question indique clairement que le problème n'est pas ce que le code renvoie, mais la requête qu'il exécute en dessous.

0voto

Kilazur Points 528

Lorsque vous utilisez un List vous utilisez Linq-To-Object qui fonctionne sur IEnumerable .

Et, en effet, IEnumerable va d'abord charger toutes les données en mémoire avant d'y appliquer Take.

Ce que vous voulez utiliser est IQueryable qui est Linq-to-Sql .

Donc, soit vous modifiez vos méthodes pour retourner un IQueryable<MyObj> ou appelez votre chaîne Linq avec AsQueryable() comme ça :

var entries = _DbContext.ReportNewEntries.AsQueryable()
    .OrderBy(a => long.Parse(a.Id)).Where(a => long.Parse(a.Id) > id).Take(1000);

0voto

Florin Nedelcu Points 21

Quelle base de données utilisez-vous ? Quelle version de .NetCore ? Quel fournisseur de données ? Certains fournisseurs de base de données peuvent avoir des problèmes pour traduire certaines instructions linq en sql. Dans ce cas, il faut exécuter une autre requête dans la base de données (généralement en prenant toutes les données) et exécuter la requête linq en mémoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X