[.net] DAL arraylists of datatables laten returnen

Pagina: 1
Acties:
  • 107 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
Na een hele berg topics hier op GoT erover gelezen te hebben, is het voor me toch nog niet geheel duidelijk wat ik het beste kan gebruiken als return value van mijn DAL methodes.

Ik neig zelf naar arraylists aangezien daar kant en klare business objecten in te stoppen zijn, alleen in mijn huidige applicatie moeten nogal wat datagrids gevuld worden, dit is met een arraylist (volgens mij) niet heel gemakkelijk te doen (zonder verlies van sorteermogelijkheden, e.d.) als met datatables.

Ik zit dus nog in een dubio over wat terug te geven uit je DAL klasses. Hoe denken jullie hierover?

Acties:
  • 0 Henk 'm!

Verwijderd

Alle boeken passen de datatable aanpak toe. Ik gebruik zelf echter gewoon bl entities die ik vul vanaf een Datareader row. :) Jouw aanpak dus.

Acties:
  • 0 Henk 'm!

  • Rodyman
  • Registratie: November 2001
  • Laatst online: 08-06-2024
gebruik je ook datagrids in je GUI's ? Zo ja, hoe vul je deze dan met je business objecten?

Acties:
  • 0 Henk 'm!

Verwijderd

Een methode om je data op te halen
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public Instance getInstance(int InstanceId)
        {
            SqlCommand myCommand = new SqlCommand("upu_Instance_PageContent",Connection);
            myCommand.CommandType = CommandType.StoredProcedure;
            myCommand.Parameters.Add("@PageID", SqlDbType.Int, 4).Value = InstanceId;
            myCommand.Parameters.Add("@Status", SqlDbType.Int, 4).Value = 0;
            myCommand.Parameters.Add("@Detail", SqlDbType.Int, 4).Value = 1;
           
            Instance instance;
            Connection.Open();
            using(SqlDataReader dr = myCommand.ExecuteReader(CommandBehavior.SingleRow)) 
            {
                dr.Read();
                instance = Instance.PopulateInstanceFromIDataReader(dr);
            }
            Connection.Close();
            return instance;
            
        }


En de PopulateInstanceFromIDataReader

code:
1
2
3
4
5
6
7
8
9
10
11
12
public static Instance PopulateInstanceFromIDataReader(IDataReader dr)
{
    Instance instance = new Instance();
    instance.InstanceID = Convert.ToInt32(dr["InstanceID"]);
    instance.Label =  (string)dr["label"];
    instance.IsLastVersionPublished = Convert.ToBoolean(dr["islastversionpublished"]);
        
    instance.StartDateTime = dr["startdatetime"].GetType() == typeof(System.DBNull) ? DateTime.MaxValue : Convert.ToDateTime(dr["startdatetime"]);
    instance.EndDateTime = dr["enddatetime"].GetType() == typeof(System.DBNull) ? DateTime.MaxValue : Convert.ToDateTime(dr["enddatetime"]);
            
    return instance;
}


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Instance
{
     int instanceid;
     string label;

     public int InstanceID
     {
        get{return instanceid;}
        set{instanceid = value;}
     }
     public string Label
     {
        get{return label;}
        set{label = value;}
     }
}

Acties:
  • 0 Henk 'm!

  • pjonk
  • Registratie: November 2000
  • Laatst online: 10-09 15:33
Misschien kan je wat ideeën opdoen uit het volgende artikel:
http://www.thecodeproject.com/dotnet/DataLoaders.asp

It’s nice to be important but it’s more important to be nice


Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09-09 13:57

pjvandesande

GC.Collect(head);

Dataset zijn makkelijk alleen passen niet in een object-oriented programming model. Dit zou je kunnen oplossen door te werken met Typed Datasets. Maar waarom werken met Typed Datasets, je kunt dan net zogoed gelijk aan je Custom Entities werken.

Voor het GUI probleem zijn er een hoop interfaces die je kunt impementeren, het kost alleen wat meer werk dan bij Datasets maar je hebt de volledige controle en functionaliteit.

Ik kies vrijwel altijd nooit voor Dataset, maar altijd voor Custom Entities. Ik kan nu een hele waslijst opnoemen waarom, maar dit heeft Dino Esposito al gedaan met een artikel in MSDN Magazine van augustus 2005. Je kunt deze erbij pakken of gewoon even op deze link klikken.

Acties:
  • 0 Henk 'm!

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Maar als je DAL custom entities terug kan/mag geven dan heeft dus de DAL laag kennis van de BL? Of zie ik dit verkeerd?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09-09 13:57

pjvandesande

GC.Collect(head);

Ik zie het zo:

Databank
Database, Webservices, etc.

Transaction
Connectie / transactie.

GateWay
return: DataSet DataTable vanuit de Databank met een Transactie gegeven door de Repository.

Repository
return: Custom Entitie samen gesteld dmv Gateways met een Transactie.

[ Voor 3% gewijzigd door pjvandesande op 07-09-2005 09:00 ]


Acties:
  • 0 Henk 'm!

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Bij jou vult de Custom Entitie (custom class), welke zich in de BL bevind, zich zelf dmv een DataSet uit de GateWay?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09-09 13:57

pjvandesande

GC.Collect(head);

Kaassoevlee schreef op woensdag 07 september 2005 @ 08:56:
Bij jou vult de Custom Entitie (custom class), welke zich in de BL bevind, zich zelf dmv een DataSet uit de GateWay?
Ja, dat gebeurt in de Repository. De queries etc zitten in de implementatie van de Gateways en returnen DataTable's.

De Repository's gaan dan verschillende DataTable's combineren tot een Custom Entitie.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:21
questa: je transactie staat niet goed. Eigenlijk is het de 'client' die de transactie moet controleren.

Ik zie het eerder zo:
Je hebt je domein-classes. Je hebt repositories die je kan zien als een 'pool' waar je domein-objecten kunt uithalen en insteken. Die 'repositories' behoren eigenlijk ook tot je 'domein'.
Een repostory ziet er bv zo uit:

code:
1
2
3
4
5
6
7
class CustomerRepository
{
     public Customer GetCustomer( int customerId )
     {... }

     public void SaveCustomer(ISession s, Customer c)
}


Indien je niet de bedoeling hebt, om verschillende types v DBMS'en te benaderen, dan kan je IMHO je SQL statements rechtstreeks in je 'Repositories' hebben.
Wil je wel meerdere DBMS'en ondersteunen, dan kunnen je repositories een juiste DAL class aanspreken. In dat geval zou ik er wel voor kiezen om m'n DAL een (typed) DataSet / etc.. te laten returnen. In je repository kan je daar dan een domein object van construeren.

Je kan je repostories & domein objecten dan gewoon in een Windows/Web applicatie gebruiken (direct), of, je kan er ook een service - laag (remoting/web services) rond bouwen.
Aangezien de repositories zelf geen transacties initieren, heb je ook geen problemen. Je applicatie of je service-laag moet dat doen.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09-09 13:57

pjvandesande

GC.Collect(head);

whoami schreef op woensdag 07 september 2005 @ 09:05:
je transactie staat niet goed. Eigenlijk is het de 'client' die de transactie moet controleren..
Wij hebben besloten om de Transactie binnen de Repository's te houden omdat het toch altijd op dezelfde manier gaat:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void cmdSaveKlatn_Click(object sender, EventArgs e)
{
     ITransaction trans = Melp.CreateTransaction();
     
     try
     {
          // Je klant hoort eigelijk niet in je GUI controls te zitten, maar anders werd het voorbeeld zo lang.
          Klant klant = lstKlanten.SelectedItem[0].Tag as Klant;
          _klantRepository.Save( trans, klant );
          trans.Commit();
     }
     catch
     {
          trans.Rollback();
     }
}


Dan kan die transactie net zo goed binnen je Repository zitten.
whoami schreef op woensdag 07 september 2005 @ 09:05:Indien je niet de bedoeling hebt, om verschillende types v DBMS'en te benaderen, dan kan je IMHO je SQL statements rechtstreeks in je 'Repositories' hebben.
Wil je wel meerdere DBMS'en ondersteunen, dan kunnen je repositories een juiste DAL class aanspreken. In dat geval zou ik er wel voor kiezen om m'n DAL een (typed) DataSet / etc.. te laten returnen. In je repository kan je daar dan een domein object van construeren.
De queries staan inderdaad in de Gateways omdat er Databases en webservices ondersteunt moeten worden. Zelfs een gedeelte moest gekoppeld kunnen worden aan Xml bestanden, dus niet elke Gateway werkt met queries. Vandaar dat we hebben gekozen om het binnen de Gateways te houden die allemaal DataSets terug geven.

[ Voor 34% gewijzigd door pjvandesande op 07-09-2005 09:17 ]


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:21
questa schreef op woensdag 07 september 2005 @ 09:14:
[...]


Wij hebben besloten om de Transactie binnen de Repository's te houden omdat het toch altijd op dezelfde manier gaat:
Da's een verkeerde oplossing imho.
Stel dat je nu eens 2 domein-objecten binnen eenzelfde transactie wilt bewaren.

Stel bv, je hebt een domein object 'Account' die een bankrekening voorstelt. De ene Account wordt gedebiteerd, de andere gecrediteerd (een overschrijving dus). Die 2 dingen moeten in één transactie gebeuren.

Hoe ga je dat dan oplossen ?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09-09 13:57

pjvandesande

GC.Collect(head);

whoami schreef op woensdag 07 september 2005 @ 09:19:
[...]

Da's een verkeerde oplossing imho.
Stel dat je nu eens 2 domein-objecten binnen eenzelfde transactie wilt bewaren.

Stel bv, je hebt een domein object 'Account' die een bankrekening voorstelt. De ene Account wordt gedebiteerd, de andere gecrediteerd (een overschrijving dus). Die 2 dingen moeten in één transactie gebeuren.

Hoe ga je dat dan oplossen ?
Dan krijg je iets als: AccountRepositorieSaveRange( AccountCollection accounts )

Daarbij vallen ze binnen 1 transactie.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:21
Zolang het allemaal eenzelfde soort objecten zijn, kan je het idd zo oplossen.
Echter, vanzodra je 2 types (root)objecten binnen eenzelfde transactie wilt saven, heb je een probleem.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09-09 13:57

pjvandesande

GC.Collect(head);

whoami schreef op woensdag 07 september 2005 @ 09:26:
Zolang het allemaal eenzelfde soort objecten zijn, kan je het idd zo oplossen.
Echter, vanzodra je 2 types (root)objecten binnen eenzelfde transactie wilt saven, heb je een probleem.
Dan heb je inderdaad een probleem. Alleen dat komt bij dit project niet voor, dus dat is ook heel afhankelijk. Maar inderdaad zodra dit wel voorkomt heb je een probleem.

Je kunt ook je Repository methods nog een extra overload geven waarbij je wel een Transactie meegeven, doe je dat niet dan creeerd hij er zelf 1.

Acties:
  • 0 Henk 'm!

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Maar het is dus gebruikelijk dat je DAL DataSets terug geeft aan de BL zodat deze er business objecten mee kan vullen?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09-09 13:57

pjvandesande

GC.Collect(head);

Kaassoevlee schreef op woensdag 07 september 2005 @ 09:57:
Maar het is dus gebruikelijk dat je DAL DataSets terug geeft aan de BL zodat deze er business objecten mee kan vullen?
Precies, de BL bestaad in dit geval dus uit Repositories.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:21
questa schreef op woensdag 07 september 2005 @ 09:58:
[...]


Precies, de BL bestaadt in dit geval dus uit Repositories.
.... en je domein objecten natuurlijk.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09-09 13:57

pjvandesande

GC.Collect(head);

whoami schreef op woensdag 07 september 2005 @ 10:12:
[...]


.... en je domein objecten natuurlijk.
Inderdaad, je Domein Objects bevatten eigelijk alle BL en de Repository weet alleen dat bepaalde dingen relaties bevatten en houd hier rekening mee. Dus de echte BL zit in de Domein Objects.

Acties:
  • 0 Henk 'm!

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Ik ben altijd wel benieuwd naar concrete voorbeeld code. Heeft iemand misschien een link naar een artikel met voorbeelden hierover, of zelf ergens wat staan. Dit maakt het allemaal wat begrijpbaarder denk ik. Taal maakt natuurlijk niet uit.

"The shell stopped unexpectedly and Explorer.exe was restarted."


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:21
Kaassoevlee schreef op woensdag 07 september 2005 @ 10:19:
Ik ben altijd wel benieuwd naar concrete voorbeeld code. Heeft iemand misschien een link naar een artikel met voorbeelden hierover, of zelf ergens wat staan. Dit maakt het allemaal wat begrijpbaarder denk ik. Taal maakt natuurlijk niet uit.
Daar ben ik zelf ook altijd op zoek naar, maar echt hele goeie voorbeelden heb ik zelf ook nog niet kunnen vinden.
Er scheelt altijd overal wel wat aan, en dan nog, dan is het nog altijd afhankelijk per concreet geval.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09-09 13:57

pjvandesande

GC.Collect(head);

Kaassoevlee schreef op woensdag 07 september 2005 @ 10:19:
Ik ben altijd wel benieuwd naar concrete voorbeeld code. Heeft iemand misschien een link naar een artikel met voorbeelden hierover, of zelf ergens wat staan. Dit maakt het allemaal wat begrijpbaarder denk ik. Taal maakt natuurlijk niet uit.
Ik zou je dan eerder een goed boek aan bevelen zoals Design Patterns Explaned, minder stoffig dan het GoF boek, maar minstens zo goed.

Hoewel dit niet over de DAL explesiet gaat.
whoami schreef op woensdag 07 september 2005 @ 10:23:
[...]


Daar ben ik zelf ook altijd op zoek naar, maar echt hele goeie voorbeelden heb ik zelf ook nog niet kunnen vinden.
Er scheelt altijd overal wel wat aan, en dan nog, dan is het nog altijd afhankelijk per concreet geval.
Ik denk als je je gewoon verdiept in Desing Patterns en in het hele OO gebeuren dat je zelf een heel eind komt. Dit soort discussies zijn ook altijd leerzaam.

[ Voor 28% gewijzigd door pjvandesande op 07-09-2005 10:26 ]


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:21
Dat boek gaat meer over OO en hoe je tot dp's komt.

Je kan eerder eens Patterns of Enterprise Application bekijken, een boek dat een aantal patterns list die oa met data-access te maken hebben. Echter, ik ben zelf niet zo tevreden van de code-voorbeelden die daarin staan. Als je daar naar kijkt, dan blijf je toch nog altijd met vraagtekens zitten, gewoon omdat er veel weggeknipt is.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Er is geen perfect voorbeeld, dat weet ik. Maar ze kunnen je wel aan het denken zetten, zodat je zelf een DAL maakt welke voor jou voldoende werkt.

"The shell stopped unexpectedly and Explorer.exe was restarted."


Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09-09 13:57

pjvandesande

GC.Collect(head);

whoami schreef op woensdag 07 september 2005 @ 10:25:
Je kan eerder eens Patterns of Enterprise Application bekijken, een boek dat een aantal patterns list die oa met data-access te maken hebben. Echter, ik ben zelf niet zo tevreden van de code-voorbeelden die daarin staan. Als je daar naar kijkt, dan blijf je toch nog altijd met vraagtekens zitten, gewoon omdat er veel weggeknipt is.
Reviews op Amazon zijn niet verkeerd en hij hard covered zie ik ;)
Toch maar even besteld.

Acties:
  • 0 Henk 'm!

Verwijderd

Er is ook niet een perfecte aanpak, omdat je altijd lagen zult gaan mengen en dat roept weer discussie op over hoe je nu het beste met zoveel mogelijk code en op een zo omslachtig mogelijke manier met lagen kan communiceren. Je komt echt de meest gevarieerde samples aan code tegen, en alles om maar te zorgen dat alles zoveel mogelijk gescheiden wordt gehouden. Scheiding is niets mis mee, maar het moet geen obsessie worden en het doel ver voorbij gaan. Er zijn nogal wat developers die imo veel te ver doorslaan. :)

[ Voor 9% gewijzigd door Verwijderd op 07-09-2005 13:12 ]


Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Mensen die roepen "Dat is de verkeerde aanpak" snappen niks van data-access.

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


Acties:
  • 0 Henk 'm!

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09-09 13:57

pjvandesande

GC.Collect(head);

EfBe schreef op woensdag 07 september 2005 @ 12:57:
Mensen die roepen "Dat is de verkeerde aanpak" snappen niks van data-access.
Ik ben dan juist benieuwd naar jouw mening al founder en developer van LLBLGen Pro. ;)

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:21
Ik zie dat niemand roepen.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
questa schreef op woensdag 07 september 2005 @ 13:02:
[...]
Ik ben dan juist benieuwd naar jouw mening al founder en developer van LLBLGen Pro. ;)
Heh, nou, er is gewoon geen 'juiste' oplossing, die hangt af van hoe je met je data om WILT gaan en hoe je tegen data aankijkt.

Zie: http://weblogs.asp.net/fbouma/archive/2004/10/09/240225.aspx

Ik zie in deze thread mensen van alles adviseren, maar altijd vanuit hun EIGEN visie op data en data-access, en daar dan ook 'goed / slecht' aan verbinden. Dat is IMHO niet de juiste weg, want dan snap je er gewoon niets van: iemand die in tables denkt, in rauwe SQL en resultsets heeft het zwaar met een puur domain model en vice versa. Welke is goed/beter/best/slecht? vraag een table/sql/resultset focused persoon of het domain model hout snijdt en vraag een domain model persoon of table/rauwe sql/resultset denken hout snijdt en je krijgt hetzelfde antwoord: nee.

Anders wordt het als je met open visier gaat kijken wat de voor/nadelen zijn van iedere aanpak. Het is nl. zo dat iedere aanpak wel degelijk resultaten oplevert en dus niet kan worden afgeserveerd met "dat werkt niet" of "dat is niet goed", want dat is onzin: het werkt wel degelijk. Aan iedere aanpak kleven nadelen en voordelen. Als een persoon de nadelen van een bepaalde aanpak voor lief neemt of er niet tegenaan loopt, waarom dan die aanpak niet kiezen? Wellicht past die aanpak prima bij de persoon's werkwijze.

Ik ga nu wat zere-beentjes uitspraken doen, maar dat moet dan maar. Deze non-discussie komt meestal voor tussen mensen die in clean-room scenario's denken en nauwelijks te maken hebben met situaties waarin de door hen gepropageerde methodiek niet werkt. Voorbeeld is bv de blindheid in de domain-model wereld voor reporting. Of de blindheid in de table/rauweSQL hoek voor typed data-access. Reporting met louter objects is een drama, terwijl het een hoeksteen is van vrijwel iedere business app. Typed data-access hoeft geen probleem te zijn, maar kan nadelig werken wanneer je veel tegen runtime errors aanloopt doordat je late-binding untyped werkt met bv datatables.

Dit houdt dus in, dat je naar je situatie moet kijken, hoe wil je met je data werken, wat zijn de voor/nadelen van een bepaalde methodiek en zijn die nadelen voor lief te nemen in DIE SITUATIE of niet. Blind kiezen voor A of B omdat poppetje X zegt dat dat beter is is het domste wat je kunt doen. Beter is om een mix van technieken te gebruiken, zodat je in de ene situatie A en in de andere situatie B kunt gebruiken.

[ Voor 4% gewijzigd door EfBe op 07-09-2005 14:31 ]

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

Pagina: 1