[ASP.NET] Business objects als datasource

Pagina: 1
Acties:

  • Mephix
  • Registratie: Augustus 2001
  • Laatst online: 25-11 20:41
Ik heb een 3-tier web applicatie.

In de BLL zitten classes waaronder bijv. "Persoon". Deze heeft een zooitje properties die ik wil displayen in een GridView.

Ik heb daarom een class "Personen" die Inherits List(Of Persoon), waarin bijvoorbeeld functies als ZoekOpNaam etc. zitten. Deze class maakt via de DAL een selectie uit de database en vult zichzelf met een x aantal Persoon, afhankelijk van de uitkomst van de query.

Omdat Personen inherit van List(Of Persoon) kun je deze rechtstreeks als datasource aan bijvoorbeeld een GridView hangen. Helemaal perfect.

Nu heb ik alleen een situatie dat ik bij een postback (een RowCommand van mijn GridView) enige acties moet uitvoeren op de Persoon instance uit de Personen class die bij die row hoort. Iedere Persoon heeft bijvoorbeeld de property Geselecteerd. Zodra ik op een row click (RowCommand) moet ik van die Persoon de property Geselecteerd omzetten van true naar false of andersom.

Hiervoor moet ik alleen in mijn codebehind bij een postback wel de beschikking hebben over de oorspronkelijke instance van Personen. Oftewel, deze moet bij postbacks bewaard blijven en toegankelijk zijn.

Nu heeft de GridView de DataSource property die bij een postback dus Nothing is (aangezien databinding alleen gebeurd If Not Page.PostBack). Verder heeft iedere row een property DataItem, maar die is ook Nothing.

Wel begrijpelijk, maar hoe krijg ik het zo voor elkaar dat mijn Personen class in dit geval bewaard wordt in cache/viewstate/DataKeys zodat ik na een RowCommand wijzigingen kan aanbrengen in de onderliggende classes ?

  • Mastermind
  • Registratie: Februari 2000
  • Laatst online: 29-11 15:35
Je moet zorgen dat de primary key ook door de query in de class Personen teruggegeven wordt in de resultset (bijv. PersoonID)
Dan moet je bij de property DataKeyNames PersoonID invullen.

Als je een row update, moet dit event gevuurd worden:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
private int persoonID
{
      get { return (int)ViewState["persoonID"]; }
      set { ViewState.Add("persoonID", value);  }
}

protected void gvPersonen_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridView grid = (GridView)sender;
int PersoonID = (int)grid.DataKeys[e.RowIndex].Value;
persoonID = PersoonID; // zet in viewstate
}

  • Mephix
  • Registratie: Augustus 2001
  • Laatst online: 25-11 20:41
Mastermind schreef op dinsdag 29 mei 2007 @ 16:42:
Je moet zorgen dat de primary key ook door de query in de class Personen teruggegeven wordt in de resultset (bijv. PersoonID)
Dan moet je bij de property DataKeyNames PersoonID invullen.

Als je een row update, moet dit event gevuurd worden:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
private int persoonID
{
      get { return (int)ViewState["persoonID"]; }
      set { ViewState.Add("persoonID", value);  }
}

protected void gvPersonen_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridView grid = (GridView)sender;
int PersoonID = (int)grid.DataKeys[e.RowIndex].Value;
persoonID = PersoonID; // zet in viewstate
}
ok, met deze methode heb ik de PersoonID weer terug. Maar dit zou betekenen dat ik:

Een nieuwe Personen moet maken (op dezelfde manier als bij het vullen van het grid)
Door de instances van Persoon moet gaan, tot ik de persoon met PersoonID tegenkom
Hier de nodige acties op moet uitvoeren
De nieuwe Personen als datasource aan mn datagrid moet hangen
Databinden

Met name het opbouwen van een nieuwe instance van Personen vind ik vervelend. Deze is bijv. gebaseerd op Personen.ZoekOpNaam("piet"), welke een flinke lijst kan zijn. Daarbij moet ik die searchphrase ergens opslaan, zodat ik bij postback in bijvoorbeeld een event van het grid een nieuwe Personen kan maken op basis van dezelfde searchphrase.

Dit zorgt dus ook voor veel (onnodige) queries, zowel voor de ZoekOpNaam actie, als het vullen van de properties van de verschillende instances van Persoon.

Zijn er nog andere manieren om dit te doen ?

  • Mephix
  • Registratie: Augustus 2001
  • Laatst online: 25-11 20:41
Mag ik deze ff schoppen ?

Waar ik nog steeds naar op zoek ben is een juiste koppeling tussen business objects en databound controls in ASP.NET. Het gaat met niet zozeer om een specifiek probleem, maar meer een algemene best pratices ofso om dit aan te pakken.

Wat ik dus eigenlijk wil is bij een postback (meestal een rowcommand event van gridview/datalist etc) de business objects die oorspronkelijk als datasource zijn gekoppeld weer terug hebben.

Op die manier kan ik bijv. op die class de functie Select() aanroepen... of ToggleSelect.. nouja, whatever eigenlijk. Hierna eventueel weer een databind om het geheel weer aan het control te knopen.

Misschien zit ik met die hele List(OF T) -> DataSource -> DataBind wel helemaal in een verkeerde richting te denken... maar dan zou ik ook graag willen weten hoe jullie zoiets aanpakken.

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20:39

gorgi_19

Kruimeltjes zijn weer op :9

Na een postback is je datasource weer leeg. Of je moet met datakeys gaan werken, of je moet a.d.h.v de ID een nieuw object uit je datalaag halen of je moet de boel meesturen in de viewstate. Dat laatste is niet aan te raden en kan vrij snel performanceproblemen opleveren.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • Mephix
  • Registratie: Augustus 2001
  • Laatst online: 25-11 20:41
De objects meesturen in de viewstate is inderdaad geen oplossing. Volgens mij moeten deze dan ook allen serializable zijn etc, wat een hoop extra werk vergt en uiteindelijk is het gewoon geen goed idee om deze met een viewstate via de client mee te sturen. Zo'n class (zeker als deze weer subclasses en collections heeft) kan aardig groot worden.

Wat ik me niet kan voorstellen is dat hier niet gewoon een algemene werkwijze voor is. Als ik eenmaal een zoekopdracht heb gedaan op de database... en het resultaat daarvan staat in memory op de server (in de vorm van business objects), dan is het toch absurd als ik dit bij een postback opnieuw zou moeten doen ?

Misschien zou ik iets van cache of sessions oid kunnen gebruiken om deze gegevens te bewaren, maar als dit Microsoft's manier zou zijn, zou dit veel logischer/makkelijker te implementeren zijn.
Pagina: 1