Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[C#] DataSource bewaren tbv. Paging

Pagina: 1
Acties:

  • Mephix
  • Registratie: Augustus 2001
  • Laatst online: 15-03 08:21
Ik wil gebruik maken van een Repeater control om bepaalde data weer te geven. Daarbij moet ook gebruik worden gemaakt van paging.

De data zelf zit in dit geval in business objecten en worden via een collection als datasource aan het Repeater control gehangen.

Dus, ongeveer zoiets:

HTML:
1
2
3
4
5
6
<asp:Repeater runat="server" ID="MyRepeater">
    <ItemTemplate>
        <%# Eval("Voornaam") %> <%# Eval("Achernaam") %><br />
        <%# Eval("Telefoonnummer") %>
    </ItemTemplate>
</asp:Repeater>


En de codebehind:
C#:
1
2
3
4
5
6
7
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostback) {
        MyRepeater.DataSource = GetContactpersonen;
        MyRepeater.DataBind();
    }
}


Stel dat ik die code uit wil breiden om paging mogelijk te maken, dan wordt het dus zoiets:

C#:
1
2
3
4
5
6
7
8
9
10
11
protected void Page_Load(object sender, EventArgs e)
{
    PagedDataSource pageddata = new PagedDataSource();
    pageddata.DataSource = GetContactpersonen;
    pageddata.AllowPaging = true;
    pageddata.PageSize = 7;
    pageddata.CurrentPageIndex = 0;
    
    MyRepeater.DataSource = pageddata;
    MyRepeater.DataBind();
}


Wat me niet lekker zit is dat ik nu noodgedwongen de GetContactpersonen bij iedere page load uit moet voeren. Daar stappen bijna alle PagedDataSource how-to website's zonder moeite overheen. In het ene voorbeeld is een nog een IsPostback check... het volgende voorbeeld issie ineens weg :+

De vraag is nu wel.. waar laat ik het resultaat van GetContactpersonen bij een postback?

De methodes die ik tot nu toe bedacht had waren ViewState, de Session of de application Cache. Eigenlijk heb ik bezwaar tegen alle 3 de methodes.

- ViewState... not done.. je kunt geen halve datasets in je viewstate gaan proppen en heen en weer blijven posten.
- Session... te losjes, het leeft niet in de scope van de pagina en moet achteraf weer opgeruimd worden om niet tot het einde van de sessie in het geheugen te blijven staan.
- Cache, eigenlijk zelfde bezwaren als in Session

Dus... wat is hier nu best practice om de resultaten van bijv. een query als datasource aan een control te hangen.. EN deze daarbij te bewaren voor acties na een postback ?

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-11 11:40

Janoz

Moderator Devschuur®

!litemod

Er is nog een 4e methode en dat is bij het nieuwe request weer gewoon de hele dataset ophalen. Dat klinkt misschien veel load, maar uiteindelijk valt het best mee. Zeker wanneer je bedenkt dat dit niet de memory bezwaren heeft als de andere 3 opties.

- edit -
hmm, ik lees te snel.. Dat is je huidige oplossing waar je ook niet lekker mee zit :D.

Maar goed, wanneer je je zorgen maakt over deze aanpak dan zou ik eerder de richting bewandelen waarbij je de business logic om een specifieke pagina kunt vragen (als in, doe mij de resultaten in deze volgorde en lever item x t/m x+50 op)

[ Voor 41% gewijzigd door Janoz op 25-09-2008 15:14 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Mephix
  • Registratie: Augustus 2001
  • Laatst online: 15-03 08:21
Het klinkt alleen zo tegenstrijdig om een collectie van 100 business objecten bij elke postback opnieuw te vullen, terwijl je er per postback maar 10 nodig hebt bijvoorbeeld.

Dan zou je eerder verwachten dat er een mogelijkheid is om dit eenmalig te doen en deze te bewaren zodat je er per page 10 uit kunt halen.

Er wordt bij verschillende trainingen ook gesproken over het "Chunky, not chatty" principe, waarbij je in 1 keer de juiste data ophaalt en niet voor iedere dingetje opnieuw je datasource gaat opbouwen.

Het business object zou natuurlijk de mogelijkheid kunnen krijgen om een bepaalde subset te retourneren, maar dan zou je in dezelfde lijn ook sorting en andere zaken bij het business object moeten leggen.. en dat vind ik dan toch meer taken die bij de presentatie horen te liggen.

Het zou eigenlijk een soort viewstate-principe moeten zijn die serverside wordt geregeld. Dus de hele datasource wordt bewaard.. het gedeelte dat via de PagedDataSource aan de Repeater wordt gehangen wordt meegestuurd naar de client.. maar de oorspronkelijke datasource wordt vanuit memory bij een postback weer opgebouwd.

- edit -
in dit geval komt de data overigens van een webservice af.. dus iedere postback die service raadplegen is gewoon niet netjes...

[ Voor 6% gewijzigd door Mephix op 25-09-2008 15:39 ]


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Waarom maak je dan niet gebruik van client-sided viewstates? Je kunt dan kiezen uit de viewstate via een windows service op te slaan of via een database. Alleen het ViewStateID staat dan nog in de postback, maar de viewstate data wordt door de server dan weer zelf opgehaald (vergelijkbaar met cookie vs session).

Een andere oplossing is dat je de 'SavePageStateToPersistenceMedium' en 'LoadPageStateFromPersistenceMedium' van je Page override en zelf de viewstate ergens opslaat.

If it isn't broken, fix it until it is..


  • labee
  • Registratie: November 2002
  • Laatst online: 10-09-2022
Waarom gebruik je geen DataPager control?
http://www.asp.net/learn/3.5-videos/video-221.aspx

http://www.labee.nl


  • 418O2
  • Registratie: November 2001
  • Laatst online: 18:43
En anders kan je ook nog een gridview gebruiken. Heeft een standaard paging (en ook sorting, maar dat is lastiger volgens mij) functie.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-11 11:40

Janoz

Moderator Devschuur®

!litemod

Mensen, we kunnen hier wel met componenten gaan smijten, maar het is misschien handig om aan te geven op wat voor manier deze componenten het probleem van de topicstarter wegnemen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-11 11:40

Janoz

Moderator Devschuur®

!litemod

Niemand_Anders schreef op donderdag 25 september 2008 @ 15:54:
Waarom maak je dan niet gebruik van client-sided viewstates? Je kunt dan kiezen uit de viewstate via een windows service op te slaan of via een database. Alleen het ViewStateID staat dan nog in de postback, maar de viewstate data wordt door de server dan weer zelf opgehaald (vergelijkbaar met cookie vs session).

Een andere oplossing is dat je de 'SavePageStateToPersistenceMedium' en 'LoadPageStateFromPersistenceMedium' van je Page override en zelf de viewstate ergens opslaat.
Maar dan heb je weer precies dezelfde bezwaren als bij het opslaan in de sessie. In principe is dit niet veel meer dan een implementatie van die sessie oplossing. Of mis ik iets?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 10:25

gorgi_19

Kruimeltjes zijn weer op :9

Links om rechtsom, je moet je eigen oplossing schrijven hiervoor. Leuk die paging mogelijkheden, maar je pompt nog steeds veel te veel records over. Of je het nu naar de viewstate stuurt (en alle records dus bij de client zet), session (alle records in het geheugen, per user) of cache zet (alle records in het geheugen, applicationwide) zet, je haalt vrij snel veel te veel op. Pagina 1 / 2 / 3 zal veel bekeken worden, 4+ nauwelijks, vermoed ik.

Wat is er mis met een custom paging waarin je alleen de juiste hoeveelheid records ophaalt? Wellicht dat een outputcache of zelf een cache implementeren met httpruntime.cache een oplossing biedt.

Niet alles is met sleur en pleur standaard controls op te lossen :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Janoz schreef op vrijdag 26 september 2008 @ 10:07:
[...]

Maar dan heb je weer precies dezelfde bezwaren als bij het opslaan in de sessie. In principe is dit niet veel meer dan een implementatie van die sessie oplossing. Of mis ik iets?
Het voordeel van de ViewState is dat het wel in de scope van de Page zit ( Al sla je die wel buiten de scope om op ). Je houd inderdaad het probleem dat het waarschijnlijk langer in je geheugen blijft staan dan strikt noodzakelijk.

Met grote datasets zul je inderdaad moeten zorgen dat de viewstate server side opgeslagen word.

Als het echt problemen geeft om elke keer de complete dataset op te halen zou ik inderdaad gewoon zorgen dat je al een gepagde dataset ophaalt zoals Janoz en gorgi_19 zeggen.
Maar goed, wanneer je je zorgen maakt over deze aanpak dan zou ik eerder de richting bewandelen waarbij je de business logic om een specifieke pagina kunt vragen (als in, doe mij de resultaten in deze volgorde en lever item x t/m x+50 op)

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • EfBe
  • Registratie: Januari 2000
  • Niet online
ObjectDataSource gebruiken, tezamen met een webgrid, of zelf gaan pagen door de Get routine (waarom is dat een property in jouw code? :X) de page te passen en het daar op te lossen.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Mephix
  • Registratie: Augustus 2001
  • Laatst online: 15-03 08:21
gorgi_19 schreef op vrijdag 26 september 2008 @ 10:34:
Links om rechtsom, je moet je eigen oplossing schrijven hiervoor.
...
Niet alles is met sleur en pleur standaard controls op te lossen :)
Ow das ook echt het probleem niet :) Ik was alleen op zoek naar ideeën voor een soort best-practice, omdat de manieren die ik tot nu toe bedacht had in mijn ogen toch grote nadelen hadden.

Een soort tussenoplossing tussen viewstate en session zou kunnen zijn de data in de sessie op te slaan (dus niet in de scope van de page), met een key (guid ofso) die ik via de viewstate ook aan de repeater hang. Zo is de data ook page-safe zeg maar.. stel dat een bezoeker 2x dezelfde pagina opent, met verschillende zoekopdrachten.. dan staat het resultaat van de zoekopdracht onder 2 verschillende keys in de sessie (= goed).

Enige nadeel daarbij is dat de data gedurende de sessie in memory blijft staan en dat kan overbodige memory usage betekenen. Maar ik denk dat dat nog altijd beter is dan caching (op zoekresultaten... onzinnig idee...) en het opslaan van alle data in de viewstate (teveel data als postback).

En nee... GetContactpersonen of iets dergelijks is geen property van m'n business object 8)7 dit was slechts voorbeeld code om even aan te geven waar de schoen knelt ;)

Voor de mensen die doorhadden waar het over ging 8) tnx voor de input !

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 16-10 10:47
Mephix schreef op maandag 29 september 2008 @ 09:07:
[...]
stel dat een bezoeker 2x dezelfde pagina opent, met verschillende zoekopdrachten.. dan staat het resultaat van de zoekopdracht onder 2 verschillende keys in de sessie (= goed).
Het is wel heel afhankelijk van hoe dynamisch je data is. Als je data veel veranderd dan loopt je bezoeker het risico om tegen verouderde data aan te kijken.
Maar goed dat terzijde vindt ik imho dit nog steeds geen goed alternatief voor het gepagineerd ophalen van je data. Waarom zou je je complete dataset ophalen als je maar een klein deel ervan gebruikt/toont? 8)7

Ga ook eens na hoe groot je sessies worden. Werkt deze oplossing ook nog als je resultaat 12mb aan data is? Nou klinkt GetContactPersonen niet als iets wat een dergelijke hoeveelheid zal genereren, maar misschien ben je van plan om dit te implementeren in andere situaties waar dit wel
een reële situatie is. Google eens op "session size and performance asp.net" en je zult er achter komen dat het dumpen van grote hoeveelheden gegevens in je sessie niet straffeloos gedaan kan worden.
in dit geval komt de data overigens van een webservice af.. dus iedere postback die service raadplegen is gewoon niet netjes...
Het niet gepagineerd ophalen van je data, dat is pas niet netjes. ;) Dat je iedere postback je gegevens opnieuw ophaalt is een implementatie detail. Je zou het prima kunnen verbouwen dat als er pas op een bepaalde zoek knop wordt gedrukt je data wordt opgehaald. Zorg dat viewstate op je grid control aanstaat en voila.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Het niet gepagineerd ophalen van je data, dat is pas niet netjes
.
Paging in een database werkt ook met het elke keer opnieuw uitvoeren van de query, dus het is maar net waar je je zwaartepunt wilt leggen: geheugen is niet zo duur namelijk.

Het put is WEL, dat topicstarter iets opnieuw wil uitvinden wat al gedaan is, nl. in de objectdatasource. Tuurlijk moet je zelf nog even de paging uitvoeren maar caching van data etc. is al geregeld.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com

Pagina: 1