Einer der sieben Todsünden ist Völlerei, übersetzt wohl auch als Verschwendung zu bezeichnen. Was heute von den Hard uns Softwareherstellern an unnötigen Datenmengen im Netzwerk erzeugt wird, kann man ohne Übertreibung als Überflüssig bezeichnet werden. So basieren die meisten Service Architekturen auf dem Muster “Hole Daten” - “Ändere Datensatz”.
Das wollen wir ändern in “Hole nur die Daten die Du jetzt brauchst”. Altbekannt als Paging.
In der ASP.NET Web Service API ist dies vorgesehen, erfordert aber ein wenig Code (hier VB.NET). Zum Vergleich auch den vorigen Blog Artikel
Public Function GetValues() As IQueryable(Of Customer1)
Dim ctx As New NorthwindEntities
Dim q = From c In ctx.Customers
Order By c.Customer_ID
Select New Customer1 With {.CustomerID = c.Customer_ID, .CompanyName = c.Company_Name,
.Address = c.Address}
Return q.AsQueryable
End Function
Immer wenn man Paging implementiert, muss auch sortiert werden, hier im LINQ Statement mit order by erledigt.
Ein Stolperstein ist, das man eine Entity Framework Entität nicht direkt als Rückgabewert verwenden kann, wenn darin eine Relation angegeben worden ist. In meinem Beispiel ist im EF Model Customers und Order referenziert.
Fehlermeldung
cannot be serialized to JSON because its IsReference setting is 'True'
Also muss ich einen manuellen Typ Customer1 zwischenschalten, der per LINQ gefüllt wird. Das hat den Vorteil, das auch das Paging und Grouping wie von Geisterhand erledigt wird. Alternativ kann man andere Serializer verwenden, wie JSON.NET die das wohl können.
Die WinRT METRO styled APP
Auf der Client Seite wird dann der HTTPRequest abgesetzt mit der Odata REST Query Syntax. Es werden also immer 10 weitere Records abgeholt. Weil ich den DataContract Serializer verwende, muss ein Typ Stream vorliegen. Die Klasse Customer1 habe ich manuell ins Windows 8 METRO Projekt kopiert.
Private Async Function vorclick(sender As Object, e As RoutedEventArgs) As Task
Dim uri As Uri = New Uri("http://localhost:12933/api/customers?$top=10&$skip=" +
(seite * 10).ToString)
Dim http As New HttpClient()
Dim js = (Await http.GetStreamAsync(uri))
Dim ser As New DataContractJsonSerializer(GetType(List(Of Customer1)))
Dim c As List(Of Customer1) = CType(ser.ReadObject(js), List(Of Customer1))
Listview1.ItemsSource = c
seite += 1
End Function
Natürlich kann man auch die Methode für zurück implementieren. Mein Windows 8 Prototyp hat den auch in der Tat.
<ListView HorizontalAlignment="Left"
VerticalAlignment="Top" x:Name="Listview1" Width="200" DisplayMemberPath="CompanyName"/>