2008-12-08 12 views
13

Ist es möglich, "Paging" -Funktionalität in Linq-Abfragen zu verwenden? Lassen Sie uns sagen, dass ich einige XML wie dieses:Newbie LINQ-Frage: ist Paging in LINQ-Abfragen möglich?

<Root> 
    <BetaSection> 
     <Choices> 
      <SetA> 
       <Choice id="choice1">Choice One</Choice> 
       <Choice id="choice2">Choice Two</Choice> 
       <Choice id="choice3">Choice Three</Choice> 
       . 
       . 
       . 
       <Choice id="choice48">Choice Forty-Eight</Choice> 
       <Choice id="choice49">Choice Forty-Nine</Choice> 
       <Choice id="choice50">Choice Fifty</Choice> 
      </SetA> 
     </Choices> 
    </BetaSection> 
</Root> 

Wenn ich Paging-Funktionalität implementieren wollte, würde ich in der Lage sein, ein zu einer LINQ-Abfrage Offset bereitzustellen, so dass an der 11. Element und endet am 20. beginnen könnte Element? Wenn ja, wäre die Abfrage anders, wenn die Daten eine Liste von Objekten anstelle von XML wären?

+0

Paginierung von Linq ist möglich. Ich weiß nicht, was du erreichen willst.Wenn in der XML-Datei riesige Datensätze gespeichert sind und Sie Daten von dort per linq mit Paginierung abrufen möchten, ist dies nicht möglich. Die meiste Zeit benutzen die Leute die xml doc-Klasse, um die xml-Datei zu lesen, und dann werden die vollständigen xml-Daten in den Speicher geladen. das sollte nicht als Seitenumbruch betrachtet werden, wenn die Daten vollständig in den Speicher geladen werden. linq wird nur ein paar Daten aus dem Speicher lesen und zurückgeben ........ aber das kann nicht gesagt werden, da pagination.pagination bedeutet, dass ich nur ein paar Daten in den Speicher laden werde, die ich zeigen oder bearbeiten werde. – Thomas

Antwort

18
var q = from X in Choices.Skip((page-1)*pageSize).Take(pageSize) 
     select X; 

Nun, wenn Sie eine where-Klausel in es brauchen, wird es ein bisschen schwieriger:

var q = (from X in Choices 
     where x.SomeField == SomeValue 
     select X).Skip((page-1)*pageSize).Take(pageSize); 
+1

Für den zweiten Fall ist es wahrscheinlich einfacher, Erweiterungsmethoden zu verwenden, anstatt die Sprachsyntax zu mischen: var q = Choices.Where (x => x.SomeField == SomeValue) .Skip ((page - 1) * pageSize)) .Nehmen (pageSize); –

+0

Im ersten Fall können Sie 'from X in' und' select X' löschen. –

+1

Wird dies funktionieren, wenn Sie orderby anwenden? Ich meine, ich erwarte, dass Linq zuerst orderby und dann überspringe und nehme ... – Andry

2
var pagedData = aDataSource.Skip(20).Take(10); 

Auf diese Weise Sie 20 Elemente werden übersprungen und nimmt die nächsten 10

1

Die „Take“ und „Skip“ Erweiterungsmethoden sorgen dafür.

myQueryable = myQueryable.Skip(10).Take(10); 
3

Absolut - Skip() und Take() Paging erreichen, und werden von ziemlich viel alle unterstützten LINQ-Anbieter.

In diesem Fall sieht es so aus, als ob Sie LINQ-to-Xml verwenden. Sie können also das folgende Bit ignorieren - aber für allgemeine Informationen: Beachten Sie, dass die Daten aus einer Datenbank über eine gespeicherte Prozedur stammen schwer auf dem Server zu pagen. Sie können jedoch "UDF" s komponieren (d. H. Seiten). LINQ-to-SQL unterstützt UDFs (über [FunctionAttribute]), jedoch nicht Entity Framework. Wenn Sie automatisch generierte Datenbankabfragen verwenden, ist dies kein Problem.

Beachten Sie, dass mit xml, Sie auch viel mit XPath tun konnte - hier mit XmlDocument:

foreach (XmlElement el in doc.SelectNodes(
    "/Root/BetaSection/Choices/SetA/Choice[position() > 11 and position() < 20]")) 
{ 
    Console.WriteLine(el.GetAttribute("id")); 
} 

oder mit Skip()/Take() (noch mit XmlDocument):

foreach (var el in doc.SelectNodes(
    "/Root/BetaSection/Choices/SetA/Choice").Cast<XmlElement>() 
    .Skip(10).Take(10)) 
{ 
    Console.WriteLine(el.GetAttribute("id")); 
} 
+0

Ich habe Ihren Code gesehen, aber wenn wir mit xmldoc Klasse zu laden und XML-Datei lesen, dann zuerst alle Daten in den Speicher geladen. wenn alle Daten in den Speicher geladen werden und nur wenige von dort mit der Skip & Take-Funktion ausgewählt werden ...... wird das wirklich als Seitenumbruch betrachtet? Paginierung bedeutet, dass ich nur wenige Daten in den Speicher laden werde, die ich zeigen oder bearbeiten werde. – Thomas

1

Ja, es ist . Sie müßten die XML in ein richtiges Datasource-Format bekommen und dann diesem Thread über auf den MSDN-Foren sollten die notwendigen Schritte bieten Ihnen die Möglichkeit zu geben, wie es zu implementieren ...

MSDN - LINQ with pagination

3

Nehmen ein Blick auf die Queryable.Skip und Queryable.Take Methoden.

Siehe auch diese nützliche extension methods für Paging,

mit, dass Methoden, die Sie dies wie folgt tun:

List<string> names = new List<string>(); 
names.AddRange(new string[]{"John","Frank","Jeff","George","Bob","Grant", "McLovin"}); 

foreach (string name in names.Page(2, 2)) 
{ 
    Console.WriteLine(name); 
} 
3

James Curran es richtig ist, können Sie das vereinfachen, indem eine Erweiterungsmethode für die Wiederverwendung zu schaffen später.

könnten Sie ändern den Code auch Sie ein Objekt zurückzugeben, wie viele Elemente gesamt sind in der Liste verfolgen können und wie viele Seiten es sollte auf der pagesize und pageindex basieren.

public static IQueryable<T> ToPageOfList<T>(this IQueryable<T> source, int pageIndex, int pageSize) 
{ 
    return source.Skip(pageIndex * pageSize).Take(pageSize); 
} 

//Example 
var g = (from x in choices select x).ToPageOfList(1, 20);