Toon posts:

[ASP.NET] Cross reference / nhibernate

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

Verwijderd

Topicstarter
Ik zit me een design issue, en waarschijnlijk gewoon een bad design issue.

Ik heb een bll class, waarin ik een entity class heb gedefinieerd. Eerder riep ik direct nhibernate aan vanuit de bll.

Entity entity = (Entity) session.Load(typeof(Entity),objectId);

Ik wil nu de nhibernate logica verplaatsen naar een dal, en er een provider van maken zodat ik op een later moment bijvoorbeeld een andere provider kan gebruiken in plaats van nhibernate.

Waar ik tegenaan loop, is dat ik in de dal dan gebruik wil maken van de Entity class. Ik heb in de bll een reference naar de dal, maar in de dal dan ook een reference naar de bll om gebruik te kunnen maken van het Entity object.

Hoe kan ik dit het slimste aanpakken? Ik zat te denken om in de dal een BaseObject aan te maken, Entity in de bll hiervan over te laten erven, en dan in de bll een cast te doen naar Entity op het door de dal teruggegeven BaseObject.

[ Voor 11% gewijzigd door Verwijderd op 27-01-2007 22:23 ]


Verwijderd

C#:
1
Entity entity = (Entity) session.Load(typeof(Entity),objectId);


Dit kun je encapsulen in de DAL in 2.0 door bijvoorbeeld:
C#:
1
2
3
4
5
6
7
public T Get(int id) 
{
  return session.Load(typeof(T),id);
}

DAL<Entity> dal = new DAL<Entity>();
Entity object = dal.Get(id);

[ Voor 3% gewijzigd door Verwijderd op 27-01-2007 23:07 ]


Verwijderd

Topicstarter
Dus generics zijn de enige echt goede manier?

Verwijderd

Verwijderd schreef op zaterdag 27 januari 2007 @ 23:12:
Dus generics zijn de enige echt goede manier?
Het is wel de makkelijkste manier :) En in dit geval ook de beste inderdaad denk ik.

Verwijderd

Topicstarter
Verwijderd schreef op zaterdag 27 januari 2007 @ 23:22:
[...]


Het is wel de makkelijkste manier :) En in dit geval ook de beste inderdaad denk ik.
Het is als je het zo bekijkt wel de mooiste manier, alleen moet ik dan versie 1.2 van nhibernate gaan gebruiken in verband met generics support.

Verwijderd

Verwijderd schreef op zaterdag 27 januari 2007 @ 23:25:
[...]


Het is als je het zo bekijkt wel de mooiste manier, alleen moet ik dan versie 1.2 van nhibernate gaan gebruiken in verband met generics support.
Nee hoor, dat hoef niet ;). Kijk maar eens naar het voorbeeld. Ik heb alleen de DAL generic gemaakt. Het hele NHibernate gebeuren is dat niet.

[ Voor 10% gewijzigd door Verwijderd op 27-01-2007 23:26 ]


Verwijderd

Topicstarter
Verwijderd schreef op zaterdag 27 januari 2007 @ 23:26:
[...]


Nee hoor, dat hoef niet ;). Kijk maar eens naar het voorbeeld. Ik heb alleen de DAL generic gemaakt. Het hele NHibernate gebeuren is dat niet.
Je hebt helemaal gelijk, bedankt voor je antwoord ik ga daar is mee verder pielen :)

Verwijderd

Topicstarter
Even een update, je bent alsnog gebonden aan 1.2. Je kunt namelijk in mijn situatie van de generic niet het type opvragen. typeof(T) zal dus ook niet gaan werken.

Je krijgt dan ook netjes "Error implicitly convert type 'object' to 'T'. An explicit conversion exists (are you missing a cast?)"

De class met generics wordt in dit geval (Load is deprecated, dus in dit geval Get)

public T Get(int id)
{
return session.Get<T>(id);


}

[ Voor 70% gewijzigd door Verwijderd op 28-01-2007 14:56 ]


Verwijderd

Bij de class ff toevoegen: where T : new()

C#:
1
2
3
4
5
6
7
8
public T Get(int id)  
{ 
  T t = new T();
  return session.Load(t.GetType(),id); 
} 

DAL<Entity> dal = new DAL<Entity>(); 
Entity object = dal.Get(id);


Dit zou moeten werken.

Verwijderd

Topicstarter
Nope ook niet :)

"Cannot create an instance of the variable type 'T' because it does not have the new() constraint"

Ik heb quick n dirty even het volgende gedaan in de dal

code:
1
2
3
4
5
6
7
8
9
10
11
12
    public T Get(int id)   
            {
                Configuration cfg = new Configuration();
                cfg.AddAssembly("Modules.Business");

                ISessionFactory factory = cfg.BuildSessionFactory();
                ISession session = factory.OpenSession();
                ITransaction transaction = session.BeginTransaction();

              T t = new T(); 
              return session.Load(t.GetType(),id);  
            }


En in de bll

code:
1
2
3
4
5
6
7
8
9
namespace Modules.Business.Website
{
    public class Website : Entity
    {
    
        public string getRewritePath(int id)
        {
            HibernateDAL<Entity> dal = new HibernateDAL<Entity>(); 
            Entity entity = dal.Get(id);

Verwijderd

Topicstarter
Ik zit zowiezo nog met een andere issue, want Website is afgeleid van Entity maar bevat een extra property.

HibernateDAL<this> dal = new HibernateDAL<this>();
Website entity = dal.Get(id);

werkt niet


HibernateDAL<Entity> dal = new HibernateDAL<Entity>();
Website entity = (Website)dal.Get(id);

werkt ook niet. Dus ik zit nu uit te vogelen hoe ik afgeleide classes via dezelfde dal toch kan ophalen, ondanks het feit dat je dan wel een andere mapping nodig hebt ivm de nieuwe property.

Verwijderd

Zowiezo moet je dan in Hibernate dan een eigen XML definieren. Het is dan ook logisch om gewoon het volgende te doen:

C#:
1
2
HibernateDAL<Website> dal = new HibernateDAL<Website>(); 
Website entity = dal.Get(id);

Verwijderd

Topicstarter
Ik had dat inderdaad al gedaan, ik stond alleen even vreemd te kijken dat this niet werd geaccepteerd, omdat ik verwachte dat de compiler zelf wel kon zien dat het object verwees naar de class Website. :)

Ik verwachtte verder ook dat nhibernate om kon gaan met overgeerfde entities, met een eigen mapping, dus ook daar wordt iets anders voor bedacht.

[ Voor 26% gewijzigd door Verwijderd op 28-01-2007 17:32 ]


  • Sjaaky
  • Registratie: Oktober 2000
  • Laatst online: 14:49
Jullie vergeten allebei de <T> achter Get ;)

code:
1
2
3
4
public T Get<T>(int id)  
{ 
  return session.Load(typeof(T), id); 
}

Verwijderd

Topicstarter
Sjaaky schreef op zondag 28 januari 2007 @ 22:04:
Jullie vergeten allebei de <T> achter Get ;)

code:
1
2
3
4
public T Get<T>(int id)  
{ 
  return session.Load(typeof(T), id); 
}
Is dat puur semantisch, want zonder werkt het namelijk hier ook. :?

Verwijderd

Sjaaky schreef op zondag 28 januari 2007 @ 22:04:
Jullie vergeten allebei de <T> achter Get ;)

code:
1
2
3
4
public T Get<T>(int id)  
{ 
  return session.Load(typeof(T), id); 
}
Die is ook helemaal niet nodig.

  • tijn
  • Registratie: Februari 2000
  • Laatst online: 02-11 15:59
Om nog even terug te komen op de oorspronkelijke vraag: je kunt ook je business layer nog opsplitsen in een laag met de entities (domain laag) en een service laag. De service laag refereert dan naar de DAL en de domain laag. De DAL refereert alleen naar de domain laag. Deze domain laag refereert verder nergens naar toe.
Het is een kwestie van wat je persoonlijk lekker vindt werken. Met een aparte service laag bestaat wel het risico dat e.e.a. wat procedureler gaat worden (google maar op anemic domain model).

Overigens moet ik zeggen dat ik die oplossing met de generic DAL ook leuk vind :).

Cuyahoga .NET website framework


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Een generic dal die je zo uit kunt swappen voor een andere is een myth. Het zit hem niet in de persistence engine die je niet uit kunt swappen, maar de code die JIJ schrijft om entities te creeren (mocht je een Dyn. proxy based o/r mapper gebruiken), te fetchen en te persisten: iedere o/r mapper gebruikt zn eigen classes en query language daarvoor.

o/r mappers zijn allang geen simpele lees/schrijf engines meer, maar volledige entity / domain managers, en dat heeft als effect dat je applicatie daar dus mee integreert.

Dit is niet erg, het is een gevolg van het outsourcen van een service, zodat je die zelf niet meer hoeft te schrijven. Maar ik zou me de moeite besparen veel tijd te steken in het generiek maken van een dal zodat je hem kunt swappen met een andere.

[ Voor 37% gewijzigd door EfBe op 29-01-2007 09:02 ]

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


  • tijn
  • Registratie: Februari 2000
  • Laatst online: 02-11 15:59
Ik bedoelde meer generic DAL als in het voorbeeld hierboven met generic classes om het probleem van de cross-references te omzeilen.

Verder heb je natuurlijk wel gelijk. De hedendaagse O/R mapper is veel meer dan alleen maar een simpele DAL. Het nadeel is dan meteen ook dat de O/R mapper zich nogal nadrukkelijk kan manifesteren binnen een applicatie. Zeker als je net begint met O/R mapper kan dat een wat ongemakkelijk gevoel geven omdat je niet weet of je wel de goede oplossing gekozen hebt, maar ondertussen wel behoorlijk vast zit aan de gekozen oplossing. Vandaar dat ik prima begrijp dat TS op zoek is naar een soort van uitwisselbare DAL.

Cuyahoga .NET website framework


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Een uitwisselbare DAL is alleen mogelijk als je alles in aggregates/repositories stopt, waardoor de consuming code t.a.t. die repositories gebruikt en de feitelijke dal code daar dan in zit. Een andere manier zie ik niet eerlijk gezegd.

Maar ik zie OOK het nut niet echt van een uitwisselbare DAL. Voorbeeld: geen gridcontrol is hetzelfde. Even een paar honderd schermen omcatten van grid X naar grid Y is echt geen kattepis. Toch hoor je nooit iemand over een uitwisselbare grid, maar is een uitwisselbare dal wel vaak een heet hangijzer. Ik vind dat een beetje problemen zoeken die er niet echt zijn, want zodra je code schrijft zit je aan de middelen vast waar je dingen naar outsourced. Tuurlijk is het t.a.t. nuttig na te denken aan welke applicatie/engine je je service outsourced maar imho is het zoeken naar een uitwisselbare DAL niet echt nuttige tijdsbesteding, want je investeert erg veel tijd (en dus geld) in het zoeken naar een antwoord op de vraag "What if....", maar die vraag kun je op zoveel momenten stellen en dan blijft het vaak zo stil, omdat men veelal al weet dat die vraag hetzelfde antwoord heeft als bij de DAL: zodra je het outsourced zit je er aanvast. Dat is een keuze, maar het levert je wel veel op. Het rare is dat men bij een DAL altijd het gevoel heeft dat het daar kennelijk wel makkelijk verwisselbaar is, terwijl dat echt niet zo is, ookal doet de DAL nog zo zn best :).

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


Verwijderd

EfBe schreef op maandag 29 januari 2007 @ 13:16:
Een uitwisselbare DAL is alleen mogelijk als je alles in aggregates/repositories stopt, waardoor de consuming code t.a.t. die repositories gebruikt en de feitelijke dal code daar dan in zit. Een andere manier zie ik niet eerlijk gezegd.

Maar ik zie OOK het nut niet echt van een uitwisselbare DAL. Voorbeeld: geen gridcontrol is hetzelfde. Even een paar honderd schermen omcatten van grid X naar grid Y is echt geen kattepis. Toch hoor je nooit iemand over een uitwisselbare grid, maar is een uitwisselbare dal wel vaak een heet hangijzer. Ik vind dat een beetje problemen zoeken die er niet echt zijn, want zodra je code schrijft zit je aan de middelen vast waar je dingen naar outsourced. Tuurlijk is het t.a.t. nuttig na te denken aan welke applicatie/engine je je service outsourced maar imho is het zoeken naar een uitwisselbare DAL niet echt nuttige tijdsbesteding, want je investeert erg veel tijd (en dus geld) in het zoeken naar een antwoord op de vraag "What if....", maar die vraag kun je op zoveel momenten stellen en dan blijft het vaak zo stil, omdat men veelal al weet dat die vraag hetzelfde antwoord heeft als bij de DAL: zodra je het outsourced zit je er aanvast. Dat is een keuze, maar het levert je wel veel op. Het rare is dat men bij een DAL altijd het gevoel heeft dat het daar kennelijk wel makkelijk verwisselbaar is, terwijl dat echt niet zo is, ookal doet de DAL nog zo zn best :).
Het gaat hier niet om het maken van een uitwisselbare OR Mapper, maar om de brug te maken tussen de OR Mapper en jouw framework/code. Deze sluiten namelijk nooit aan, welke tooling je ook gebruikt. Door een extra laag er tussen te zetten kun je een hoop standaard functionaliteit al vast definieren, maar ook diverse constraints vastleggen enzovoorts. Het heeft dus wel degelijk nut en levert zelfs geld op ipv dat het geld kost.

Jouw voorbeeld slaat trouwens kant nog wal en lijkt totaal niet op de praktijk geschoeid te zijn (Wat ik raar vind als je zelf een OR mapper verkoopt). Databases en dergelijke worden namelijk velen malen vaker vervangen door andere systemen dan de front-end. Vaak wanneer men de presentatie lagen gaat vervangen, vervangt men meteen alles. Bij de achterkant wil men echter zo min mogelijk doen.

En als laatste voorbeeld:
In de bovenstaande code heb je genoeg aan 1 (base)class om alle basisfunctionaliteit in vast te leggen. Vervolgens kun je met overerving alle extra methoden toevoegen voor de overige objecten. Dat levert alleen maar tijdswinst op, want als je 30 objecten hebt met iedereen 10 standaard methoden en 2 eigen methoden, hoef je maar 70 methoden te definieeren, ipv de 360 methoden die je anders zou moeten doen.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op maandag 29 januari 2007 @ 14:25:
Het gaat hier niet om het maken van een uitwisselbare OR Mapper, maar om de brug te maken tussen de OR Mapper en jouw framework/code. Deze sluiten namelijk nooit aan, welke tooling je ook gebruikt. Door een extra laag er tussen te zetten kun je een hoop standaard functionaliteit al vast definieren, maar ook diverse constraints vastleggen enzovoorts. Het heeft dus wel degelijk nut en levert zelfs geld op ipv dat het geld kost.
oh, dus een extra laag tussen jouw en de dal code te bouwen krijg je tijd terug? Vage redenatie, temeer omdat de laag geen moer toevoegt, want al wat het doet is conversie van conventie A (jouw code) naar conventie B (de dal code) en terug. Het nut daarvan bestrijd ik en jij kennelijk niet.
Jouw voorbeeld slaat trouwens kant nog wal en lijkt totaal niet op de praktijk geschoeid te zijn (Wat ik raar vind als je zelf een OR mapper verkoopt). Databases en dergelijke worden namelijk velen malen vaker vervangen door andere systemen dan de front-end. Vaak wanneer men de presentatie lagen gaat vervangen, vervangt men meteen alles. Bij de achterkant wil men echter zo min mogelijk doen.
Ik had het niet over sqlserver vervangen voor oracle maar over het vervangen van o/r mapper A voor o/r mapper B. Maar ookal vervang je de database, dan nog heb je grote problemen. Voorbeeld: PKs van GUIDs en sqlserver, en nu ga jij die vervangen voor Oracle. Veel plezier.

Databases leven overigens meestal langer dan de applicaties die erop draaien, maar dat terzijde. En ja dat is op de praktijk geschoeid.
En als laatste voorbeeld:
In de bovenstaande code heb je genoeg aan 1 (base)class om alle basisfunctionaliteit in vast te leggen. Vervolgens kun je met overerving alle extra methoden toevoegen voor de overige objecten. Dat levert alleen maar tijdswinst op, want als je 30 objecten hebt met iedereen 10 standaard methoden en 2 eigen methoden, hoef je maar 70 methoden te definieeren, ipv de 360 methoden die je anders zou moeten doen.
Welke methods? GetCustomer(id) etc. ? Ik zie niet in hoe dit tijdwinst oplevert, want je kunt dat werk ook gewoon besparen en de dal gebruiken in je code. Tenzij je repositories gaat maken, maar daar heb jij het niet over.

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


Verwijderd

EfBe schreef op dinsdag 30 januari 2007 @ 08:03:
[...]

oh, dus een extra laag tussen jouw en de dal code te bouwen krijg je tijd terug? Vage redenatie, temeer omdat de laag geen moer toevoegt, want al wat het doet is conversie van conventie A (jouw code) naar conventie B (de dal code) en terug. Het nut daarvan bestrijd ik en jij kennelijk niet.
Ja en Nee, zie onder :). Maar volgens mij is dat ook iets persoonlijks, laten we dat maar in het midden liggen, voordat dit verzand in een compleet andere discussie.
Ik had het niet over sqlserver vervangen voor oracle maar over het vervangen van o/r mapper A voor o/r mapper B. Maar ookal vervang je de database, dan nog heb je grote problemen. Voorbeeld: PKs van GUIDs en sqlserver, en nu ga jij die vervangen voor Oracle. Veel plezier.

Databases leven overigens meestal langer dan de applicaties die erop draaien, maar dat terzijde. En ja dat is op de praktijk geschoeid.
Dan las ik dit inderdaad verkeerd. Het vervangen van de OR Mapper is het doel ook niet van de bovenstaande code. De code generiek maken om te kunnen switchen van OR Mapper is inderdaad een rare en eigenlijk absurde wens. Oracle en Guids gaan trouwens prima samen hoor tegenwoordig ;).
Welke methods? GetCustomer(id) etc. ? Ik zie niet in hoe dit tijdwinst oplevert, want je kunt dat werk ook gewoon besparen en de dal gebruiken in je code. Tenzij je repositories gaat maken, maar daar heb jij het niet over.
Nee, standaard methodes als Get, Update, Delete etc... GetCustomer is een ambigious name als je toch al bezig bent binnen een Customer. Je kunt hierbij het "Customer" gedeelte van de naam dus gewoon weglaten, aangezien deze helemaal niets toevoegt aan de naam.

Daarnaast is het wat mij betreft zeer ongewenst om zaken als SqlTypes en Nhibernate nullables in je code te gebruiken buiten de DAL. Diverse OR Mappers maken gebruik van deze types ipv de native .NET types. Hierdoor moet er zowiezo een extra laag geimplementeerd worden die de boel vertaald.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op dinsdag 30 januari 2007 @ 13:04:
Dan las ik dit inderdaad verkeerd. Het vervangen van de OR Mapper is het doel ook niet van de bovenstaande code. De code generiek maken om te kunnen switchen van OR Mapper is inderdaad een rare en eigenlijk absurde wens. Oracle en Guids gaan trouwens prima samen hoor tegenwoordig ;).
Dat is dan nieuw sinds 10gR2 ? Guids, bit fields (dus class members van type bool) etc. zijn ge-eikte voorbeelden van niet-portable types waar je rap tegen muren oploopt mbt app portabiliteit tussen db's.
Nee, standaard methodes als Get, Update, Delete etc... GetCustomer is een ambigious name als je toch al bezig bent binnen een Customer. Je kunt hierbij het "Customer" gedeelte van de naam dus gewoon weglaten, aangezien deze helemaal niets toevoegt aan de naam.
Ok, dus T Get<T, U>(param U[] pkValues)
? want anders leg je vast dat je PK's altijd int's zijn en nooit compound ;)
Daarnaast is het wat mij betreft zeer ongewenst om zaken als SqlTypes en Nhibernate nullables in je code te gebruiken buiten de DAL. Diverse OR Mappers maken gebruik van deze types ipv de native .NET types. Hierdoor moet er zowiezo een extra laag geimplementeerd worden die de boel vertaald.
Voor nullable types van een bepaalde lib valt nog wat te zeggen, omdat in .NET 1.x je geen andere keuze had. Ik dacht dat de nullable type lib van nhibernate gewoon de meest gebruikte was op .net 1.x. SqlTypes zijn inderdaad niet echt handig...

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


Verwijderd

EfBe schreef op dinsdag 30 januari 2007 @ 16:01:
[...]

Dat is dan nieuw sinds 10gR2 ? Guids, bit fields (dus class members van type bool) etc. zijn ge-eikte voorbeelden van niet-portable types waar je rap tegen muren oploopt mbt app portabiliteit tussen db's.


[...]
Wij hebben het in een oudere versie toegepast bij een klant. Ik durf niet meer te zeggen welke versie. Het was mogelijk, maar wel even uitzoekwerk. Maar inderdaad niet echt standaard ;)
Ok, dus T Get<T, U>(param U[] pkValues)
? want anders leg je vast dat je PK's altijd int's zijn en nooit compound ;)
Compound PK's vermijd ik altijd zoveel mogelijk, maar dit is inderdaad een mooie oplossing daarvoor zo op het eerste oog. Alhoewel we nu weer in een discussie komen die denk ik alleen face2face interessant en leuk is onder het genot van een biertje ipv deze thread. :) Overigens probeer je volgens mij nu ook de hele DAL generiek te maken door de mogelijkheid te geven tussen types van de PK's te kunnen switchen. Dat vind ik een beetje over done. Daarnaast prefereer ik dan gewoon een simpel design pattern wanneer je dit nodig hebt. Binnen een ontwikkelstraat/ORMapper zijn dat volgens mij de enige 2 situaties waarin je zoiets zo willen, maar dan zijn er ook weer genoeg andere oplossingen, omdat je zowiezo code genereert.
Voor nullable types van een bepaalde lib valt nog wat te zeggen, omdat in .NET 1.x je geen andere keuze had. Ik dacht dat de nullable type lib van nhibernate gewoon de meest gebruikte was op .net 1.x. SqlTypes zijn inderdaad niet echt handig...
Probleem met de nullable type van Nhibernate is, is dat je dan ook in de overige lagen waar je ze gebruikt de NHibernate dll's moet gaan referencen. Ben ik geen voorstander van, je wilt het immers gescheiden houden. Ik probeer ook zoveel mogelijk System.Data te vermijden buiten de DAL. Dat is overigens nog een behoorlijke klus (en geen vereiste) :P

[ Voor 14% gewijzigd door Verwijderd op 30-01-2007 16:41 ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op dinsdag 30 januari 2007 @ 16:35:
[...]
Wij hebben het in een oudere versie toegepast bij een klant. Ik durf niet meer te zeggen welke versie. Het was mogelijk, maar wel even uitzoekwerk. Maar inderdaad niet echt standaard ;)
Bij mijn weten kun je alleen een char(36) (al nagelang je het opslaat), of raw gebruiken, of de 16 bytes opslaan in een byte char(16) maar goed, off topic :)
Compound PK's vermijd ik altijd zoveel mogelijk, maar dit is inderdaad een mooie oplossing daarvoor zo op het eerste oog. Alhoewel we nu weer in een discussie komen die denk ik alleen face2face interessant en leuk is onder het genot van een biertje ipv deze thread. :) Overigens probeer je volgens mij nu ook de hele DAL generiek te maken door de mogelijkheid te geven tussen types van de PK's te kunnen switchen. Dat vind ik een beetje over done.
Mja, dat kan dus niet. er is niet zoiets als een 'beetje generiek', want dat doet compleet de reden waarom je uberhaupt iets generieks maakt teniet. Ik bedoel, waarom dan de moeite doen? (want dat is me nog steeds niet helemaal duidelijk)
Probleem met de nullable type van Nhibernate is, is dat je dan ook in de overige lagen waar je ze gebruikt de NHibernate dll's moet gaan referencen. Ben ik geen voorstander van, je wilt het immers gescheiden houden. Ik probeer ook zoveel mogelijk System.Data te vermijden buiten de DAL. Dat is overigens nog een behoorlijke klus (en geen vereiste) :P
Die nullable types zijn toch gewoon die van Luka? http://nullabletypes.sourceforge.net/

Ach het vermijden van references naar allerlei zaken. De energie die mensen daar soms in stoppen is zo misplaatst. "Oh jee, we referencen de o/rmapper dll in project ABC!!!", ja en? Je hele applicatie draait op die spullen dus die assembly is TOCH Ingeladen in je appdomain at runtime... De reden waarom is me nl. niet duidelijk, want je moet dan ook je complete dal generiek maken tot op de laatste centimeter. Dat levert per saldo 0.0 op, want een niet generieke dal werkt nl. ook naar behoren en is niet een teken van slechte architectuur. Immers: zodra je gaat engineeren om het engineeren (en daar komt het IMHO op neer in deze context) levert dat niet per saldo betere spullen op.

Het resultaat, bv een presentation layer die wars is van welke entity management techniek gebruikt wordt, is dat nu een voordeel? Alleen wanneer je je entity management system / ormapper wisselt. En wanneer komt dat voor? Want vergeet niet: dat swappen van ormapper is ingrijpend, ongeacht welke je gebruikt.

[ Voor 6% gewijzigd door EfBe op 30-01-2007 18:49 ]

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


Verwijderd

EfBe schreef op dinsdag 30 januari 2007 @ 18:46:

Ach het vermijden van references naar allerlei zaken. De energie die mensen daar soms in stoppen is zo misplaatst. "Oh jee, we referencen de o/rmapper dll in project ABC!!!", ja en? Je hele applicatie draait op die spullen dus die assembly is TOCH Ingeladen in je appdomain at runtime...
Dat is nu net het hele idee van een meerlagenarchitectuur en al helemaal bij .NET, waar je 1 dll kan aanpassen zonder aan de rest te zitten. Alles wat met Data te maken heeft blijft lekker in de DAL... Jouw commentaar suggereert meer iets van: "Laten we alles bij elkaar gooien, want het draait toch allemaal op dezelfde machine!". Vind ik erg vreemde argumentatie. En het is overigens minimaal 3 lagen als je al een meerlagenarchitectuur wil gebruiken: Presentatie - BLL - DAL. Je praat dus zowiezo alleen tegen business objecten en nooit tegen een ormapper vanuit de presentatie, als je een applicatie goed opbouwt. Anders heeft het eigenlijk geen enkel nut om het toe te passen.

Praktijk voorbeeld: Steeds meer bedrijven spreiden hun applicaties ook fysiek. Een or mapper gaan referencen op je presentatie is dan echt not done. Data access gebeurt op de applicatie server, of zelfs op de data server en niet op de presentatie server. Je krijgt je applicatie dan meteen retour zender.

Dat van nullable types mbt NHibernate zou idd kunnen dat dat een apart project is. Durf ik niets van te zeggen. In dat geval zou je die wel kunnen gebruiken inderdaad.

[ Voor 50% gewijzigd door Verwijderd op 30-01-2007 19:37 ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op dinsdag 30 januari 2007 @ 19:22:
[...]
Dat is nu net het hele idee van een meerlagenarchitectuur en al helemaal bij .NET, waar je 1 dll kan aanpassen zonder aan de rest te zitten. Alles wat met Data te maken heeft blijft lekker in de DAL... Jouw commentaar suggereert meer iets van: "Laten we alles bij elkaar gooien, want het draait toch allemaal op dezelfde machine!". Vind ik erg vreemde argumentatie. En het is overigens minimaal 3 lagen als je al een meerlagenarchitectuur wil gebruiken: Presentatie - BLL - DAL. Je praat dus zowiezo alleen tegen business objecten en nooit tegen een ormapper vanuit de presentatie, als je een applicatie goed opbouwt. Anders heeft het eigenlijk geen enkel nut om het toe te passen.
Nee je begrijpt niet wat ik bedoel. Ik heb het totaal niet over het samenvoegen van tiers/layers als in: prak de code allemaal maar achter het scherm, ik heb het over het gebruik van een bepaald type in tier A, B EN C. Jij probeert een bepaald type te vermijden in tier B en C om een mij onduidelijke reden. Het punt is dat een o/r mapper allang geen simpele persistence layer meer is maar een compleet entity management system, en dat heeft als gevolg dat je wellicht een of meerdere assemblies van dat system moet referencen in je andere tiers, maar dat is niet erg, want je gebruikt die code ook.

Dom voorbeeld horen? Databinding support code. Als ik jou mag geloven mag een entity class dus geen system.componentmodel types implementeren want die horen niet in die class thuis, toch? Dan gaat databinding niet lukken bij je, althans, niet zoals jij wilt.

2-way databinding in asp.net? Hoe? Middels objectdatasource? Of middels een datasourcecontrol die bij de o/r mapper hoort? Indien dat laatste krijg je wellicht meer features, maar moet je wel de assembly waar die code in zit referencen. Erg? Nou alleen mensen die niet snappen waar het werkelijk om gaat zeuren over dat soort zaken.

Overigens praat jij nog erg langs de Microsoft DNA lijnen. 3-tier development is vrij star en er zitten voordelen aan maar het is ook soms overkill omdat je tegenwoordig andere structuren hebt in je top tier, zoals pre-fab controllers in de vorm van datasourcecontrols, die je declaratief gebruikt en waarbij je eigenlijk een middletier overslaat. En waartoe behoort een customer entity class? BL tier, of DAL? Indien DAL, heb je dan niet in je BL tier veelal 'doorgeef classes', dus van die classes die feitelijk niet zoveel doen dan het doorsjoelen van commands naar beneden en data naar boven?

Begrijp me goed, het laatste wat ik propageer is het programmeren van logica achter een button handler of iets dergelijks, het liefst zie ik echter meer een MVC model ontstaan dan dat men puur terugvalt op een 3-tier model.
Praktijk voorbeeld: Steeds meer bedrijven spreiden hun applicaties ook fysiek. Een or mapper gaan referencen op je presentatie is dan echt not done. Data access gebeurt op de applicatie server, of zelfs op de data server en niet op de presentatie server. Je krijgt je applicatie dan meteen retour zender.
Wat probeer je mij nu uit te leggen, hoe je (ditributed) software maakt? :D

Jouw verhaal riekt naar klepel-klok. Een distributed applicatie is niet horizontaal gesplitst, maar vertikaal (althans, meerdere tiers). Alleen dan haal je uit je services wat er in zit. Het punt is dat bij jouw splitsingsvoorbeeld je objectgraphs heen en weer moet zenden tussen je services, wat traag is en tegen het principe indruist dat je bij service oriented architectures messaging moet gebruiken en niet het heen en weer sturen van object graphs. Het is echt dom om eerst 100.000 entities van db service naar bl service te trekken, daar dan iets te gaan doen met deze entities en dan, zeg 5.000 terug te sturen die gewijzigd zijn. Veel efficienter is dan om een service te bouwen die EN data EN manipulatie voor _die functionaliteit_ biedt op 1 machine. Dat heeft niets met het samenrapen van tiers te maken, maar met het efficient inzetten van service oriented architecture. Maar daar weet jij natuurlijk alles van ;)

Maar, stel je splitst het horizontaal, dus BL/DAL staat op bak A en GUI staat op bak B. Dan is het onmogelijk om in de GUI iets met de database te doen, logisch, dus GUI gebruikt de BL service daarvoor op bak A. Echter, de objects geproduceerd door BL, worden bv gebruikt in 2-way databinding met een datasourcecontrol of worden gebruikt voor in-memory views met in-memory filtering en changes worden getracked in een unit of work object. Services die geboden worden door de o/r mapper code. De o/r mapper code is zo opgezet dat je WEL die services in je GUI tier kunt gebruiken maar NIET persistence kunt doen, want daar heb je een ander deel voor nodig en die staat op de BL bak.

Nu wil jij beweren dat je dan dus alles in het werk stelt om die o/r mapper code NIET te gebruiken in de GUI omdat .... ja waarom eigenlijk ? Ik hoop toch van niet.

[ Voor 0% gewijzigd door EfBe op 31-01-2007 09:35 . Reden: scherpe kantjes er wat vanaf ;) ]

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


Verwijderd

Volgens mij gaan we hier eindigen in een welles nietus verhaal. Dus ik stop er hierna lekker mee. Een goede distributed applicatie is wel degelijk horizontaal gesplitst ten behoeve van bijvoorbeeld loadbalancing en schaalbaarheid. Hierdoor kun je alle lagen fysiek scheiden en dat doe je horizontaal, niet verticaal. Verticaal betekent dat elke fysieke server een stukje van alle lagen zou hebben. En dat wil je echt niet. Dat kan bijvoorbeeld voor gigantische session problemen zorgen.

Daarnaast komt ASP.NET (2.0) zelf al met een grotendeels geimplementeerd MVC model. Het is wel een discutabel punt, dus daar ga ik niet op in.

Een Customer entity hoort thuis in de BLL. Dit is een Business Object, die misschien wel in de DAL als 2 tabellen beschouwd dient te worden (1 of ander lomp voorbeeld). Je praat vanuit de GUI dan ook tegen de Customer.

Laatste opmerking:
Het is echt dom om eerst 100.000 entities van db service naar bl service te trekken, daar dan iets te gaan doen met deze entities en dan, zeg 5.000 terug te sturen die gewijzigd zijn.
Dan heb je iets compleet verkeerd gedaan als een dergelijke situatie ontstaat en bouwt.
Maar, stel je splitst het horizontaal, dus BL/DAL staat op bak A en GUI staat op bak B. Dan is het onmogelijk om in de GUI iets met de database te doen, logisch, dus GUI gebruikt de BL service daarvoor op bak A. Echter, de objects geproduceerd door BL, worden bv gebruikt in 2-way databinding met een datasourcecontrol of worden gebruikt voor in-memory views met in-memory filtering en changes worden getracked in een unit of work object. Services die geboden worden door de o/r mapper code. De o/r mapper code is zo opgezet dat je WEL die services in je GUI tier kunt gebruiken maar NIET persistence kunt doen, want daar heb je een ander deel voor nodig en die staat op de BL bak.
Je gaat hier dingen persisteren in de GUI die daar niet thuis horen. Je slaat hier bijvoorbeeld al de validaties over. Validaties horen thuis in de BLL en wanneer de objecten geen fouten bevatten dan kun je ze persisteren in de database. Dat is een zeer groot gemis in jouw bovenstaande voorbeeld.

[ Voor 48% gewijzigd door Verwijderd op 31-01-2007 11:33 . Reden: Bericht wat korter gemaakt, een lange quote kopieren voegt hier niets toe ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op woensdag 31 januari 2007 @ 11:18:
Volgens mij gaan we hier eindigen in een welles nietus verhaal. Dus ik stop er hierna lekker mee. Een goede distributed applicatie is wel degelijk horizontaal gesplitst ten behoeve van bijvoorbeeld loadbalancing en schaalbaarheid. Hierdoor kun je alle lagen fysiek scheiden en dat doe je horizontaal, niet verticaal. Verticaal betekent dat elke fysieke server een stukje van alle lagen zou hebben. En dat wil je echt niet. Dat kan bijvoorbeeld voor gigantische session problemen zorgen.
Volgens mij praten we over verschillende dingen, maar goed. :) Vertikaal splitsen levert het voordeel op dat je de distributie van je logica en waarop het werkt beter regelt. SOA specialisten zijn meer en meer het er over eens dat vertikaal splitsen beter is. Dat hoeft overigens niet van top tot bodem, dat kan ook dal + BL zijn voor een gesegmenteerd deel van je functionaliteit. Dat is wel essentieel: je gaat geen phat service maken voor je complete applicatie, maar verschillende services, en die balance je over verschillende machines.
Daarnaast komt ASP.NET (2.0) zelf al met een grotendeels geimplementeerd MVC model. Het is wel een discutabel punt, dus daar ga ik niet op in.
Ik zie de 'C' in ASP.NET absoluut niet terug.
Een Customer entity hoort thuis in de BLL. Dit is een Business Object, die misschien wel in de DAL als 2 tabellen beschouwd dient te worden (1 of ander lomp voorbeeld). Je praat vanuit de GUI dan ook tegen de Customer.
Ok, dan zijn we het daar over eens. De plaats van een entity class is overigens wel een punt van discussie, sommigen vinden het een DAL onderdeel, anderen niet. Het praten in 'BL' en 'DAL' wordt dan een lastig verhaal wanneer dit niet is gespecificeerd.
Laatste opmerking:
[...]
Dan heb je iets compleet verkeerd gedaan als een dergelijke situatie ontstaat en bouwt.
Ja dat is niet slim nee, maar met horizontale splitsing ontkom je er niet aan, want jij moet van server naar server om uberhaupt de db te bereiken, voor IEDERE functionaliteit. Vandaar mijn voorbeeld, wat overigens een echt voorbeeld is (nee, niet mijn code, klant van ons vroeg zich af waarom het toch een tijdje duurde voordat 150,000 entities waren overgepompt van machine a naar machine b. ;))
[...]
Je gaat hier dingen persisteren in de GUI die daar niet thuis horen. Je slaat hier bijvoorbeeld al de validaties over. Validaties horen thuis in de BLL en wanneer de objecten geen fouten bevatten dan kun je ze persisteren in de database. Dat is een zeer groot gemis in jouw bovenstaande voorbeeld.
Nee hoor, want die validatie zit in de entities, zoals het hoort. Verder is UI oriented validatie natuurlijk een zaak van de UI, niet van de BL.

Ik ga overigens niets persisteren in de UI, ik roep de service aan met de entities die bewerkt zijn door de UI. Echter de UI gebruikt code die onderdeel is van de o/r mapper, echter de persistence logica is niet aanwezig, dus MOET de UI de service aanroepen om uberhaupt iets te doen met de DB.

Mijn voorbeeld is bedoeld aan te geven dat het overdreven gemier van "Dit wil ik niet referencen hier", echt moet worden beargumenteerd en niet gebaseerd moet zijn op "dat hoort niet" terwijl je niet kunt aangeven waarom. Jij doet het nu ook weer: "Je gaat hier dingen persisteren in de GUI die daar niet thuis horen.". Says who? Wie bepaalt wat waar wel en niet thuishoort? Omdat de o/r mapper met 3 dll's komt mogen geen van de andere tiers die dll's referencen behalve de dal? Dat was mijn punt.

Je kunt nu wel proberen het te laten lijken alsof ik het niet snap, maar ik denk dat je daar de plank toch wat misslaat. Het punt is nl. dat ik veel mensen hoor roepen dat dit niet mag en dat niet hoort maar wanneer argumentatie ontbreekt voor die stellingen, is het IMHO zaak erop te wijzen dat het innemen van zo'n stelling ook nadelen heeft en als het innemen van die stelling niet nodig is maar je dus WEL die nadelen ondervindt, lijkt het me dus nuttig die stellingname niet te doen.

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


Verwijderd

EfBe schreef op woensdag 31 januari 2007 @ 13:17:
[...]

Volgens mij praten we over verschillende dingen, maar goed. :) Vertikaal splitsen levert het voordeel op dat je de distributie van je logica en waarop het werkt beter regelt. SOA specialisten zijn meer en meer het er over eens dat vertikaal splitsen beter is. Dat hoeft overigens niet van top tot bodem, dat kan ook dal + BL zijn voor een gesegmenteerd deel van je functionaliteit. Dat is wel essentieel: je gaat geen phat service maken voor je complete applicatie, maar verschillende services, en die balance je over verschillende machines.


[...]
Dat is inderdaad helemaal waar. BL + DAL worden vaak samen gehouden en verticaal gesplitst, omdat deze toch stateless zijn (of ieg horen te zijn).
Ik zie de 'C' in ASP.NET absoluut niet terug.


[...]
De C is ook het discussie punt ;). Ik ga die discussie niet met je voeren. Ik heb hier geen eenduidig standpunt over dat ik ook kan staven zonder oeverloos te gaan lullen.
Nee hoor, want die validatie zit in de entities, zoals het hoort. Verder is UI oriented validatie natuurlijk een zaak van de UI, niet van de BL.

Ik ga overigens niets persisteren in de UI, ik roep de service aan met de entities die bewerkt zijn door de UI. Echter de UI gebruikt code die onderdeel is van de o/r mapper, echter de persistence logica is niet aanwezig, dus MOET de UI de service aanroepen om uberhaupt iets te doen met de DB.


Mijn voorbeeld is bedoeld aan te geven dat het overdreven gemier van "Dit wil ik niet referencen hier", echt moet worden beargumenteerd en niet gebaseerd moet zijn op "dat hoort niet" terwijl je niet kunt aangeven waarom. Jij doet het nu ook weer: "Je gaat hier dingen persisteren in de GUI die daar niet thuis horen.". Says who? Wie bepaalt wat waar wel en niet thuishoort? Omdat de o/r mapper met 3 dll's komt mogen geen van de andere tiers die dll's referencen behalve de dal? Dat was mijn punt.
Dat zijn common Best Practises. Uitgedacht door mensen die al vele jaren ontwikkellen en welke uitwerkingen gestaafd worden door praktijkervaringen, net als met design patterns. Je kunt het inderdaad ook over the top doen en daar word ik ook niet vrolijk van.
Je kunt nu wel proberen het te laten lijken alsof ik het niet snap, maar ik denk dat je daar de plank toch wat misslaat. Het punt is nl. dat ik veel mensen hoor roepen dat dit niet mag en dat niet hoort maar wanneer argumentatie ontbreekt voor die stellingen, is het IMHO zaak erop te wijzen dat het innemen van zo'n stelling ook nadelen heeft en als het innemen van die stelling niet nodig is maar je dus WEL die nadelen ondervindt, lijkt het me dus nuttig die stellingname niet te doen.
Alles heeft zijn nadelen en dat is dan ook geen reden om een stelling er tegen in te nemen. Zie ook commentaar hierboven.


Laten we het erop houden dat er meer wegen naar Rome leiden en het voornamelijk ligt aan wat jij als leading ziet. Jij ziet de OR Mapper als leading merk ik (Ook logisch als je zelf een or mapper hebt gebouwt en verkoopt). Ik zie business als leading en een OR Mapper alleen als een goede toevoeging om de datalaag abstracter te maken, wat mij scheelt in ontwikkel- en testtijd . Ik werk dus vanuit de Business en wil nooit iets te maken hebben met persistentie in de UI. Ik wil maximaal Save(), Delete() en Get() aanroepen, waarna de Business/Process de rest regelt en de DAL alle database acties uitvoert. Prima, lijkt me :)

[ Voor 19% gewijzigd door Verwijderd op 31-01-2007 13:40 ]


  • BertS
  • Registratie: September 2004
  • Laatst online: 27-10 13:12
Verwijderd schreef op woensdag 31 januari 2007 @ 13:32:
Ik werk dus vanuit de Business en wil nooit iets te maken hebben met persistentie in de UI. Ik wil maximaal Save(), Delete() en Get() aanroepen, waarna de Business/Process de rest regelt en de DAL alle database acties uitvoert. Prima, lijkt me :)
Dat is precies wat EfBe je ook probeert uit te leggen. Met Get() krijg je een Entity (of ander DTO (Data transfer object) terug (die je dan netjes kunt binden in je GUI). Aan Save() geef je de gemuteerde Entity mee, waarna de Save-method de validatie kan regelen en persistance-commando's kan doorgeven aan de DAL.
Volgens mij zeggen jullie namelijk zo'n beetje hetzelfde, maar dan met andere woorden ;)

  • EfBe
  • Registratie: Januari 2000
  • Niet online
BertS schreef op woensdag 31 januari 2007 @ 14:25:
[...]

Dat is precies wat EfBe je ook probeert uit te leggen. Met Get() krijg je een Entity (of ander DTO (Data transfer object) terug (die je dan netjes kunt binden in je GUI). Aan Save() geef je de gemuteerde Entity mee, waarna de Save-method de validatie kan regelen en persistance-commando's kan doorgeven aan de DAL.
Volgens mij zeggen jullie namelijk zo'n beetje hetzelfde, maar dan met andere woorden ;)
Precies, Bert :)

Ik zie de o/r mapper niet als leading, het is een tool. Ik zie entities als leading:
http://weblogs.asp.net/fb...-is-the-Domain-Model.aspx

Overigens, is er theoretisch iets voor de zeggen om <entity>.Save(), <entity>.Get() etc. te doen, immers, het is behavior, dus hoort in de class thuis waar de behavior betrekking op heeft. Immers, waarom zou je de ene behavior wel en de andere niet in de class implementeren?

[ Voor 15% gewijzigd door EfBe op 31-01-2007 16:10 ]

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


Verwijderd

Een database model is in de praktijk absoluut niet altijd het domein model. Titel begint dus al verkeerd... Dat artikel gaat uit van de ideale situatie, de ideale situatie bestaat alleen niet.

Ff iets verder lezen de volgende keer ;)

[ Voor 66% gewijzigd door Verwijderd op 31-01-2007 15:48 ]


Verwijderd

Topicstarter
Ik volg de discussie al een paar dagen, erg interessant om de punten vanuit meerdere kanten te lezen.

Maar waar het dus op neer komt, is dat ik eigenlijk gewoon aan het over engineren ben geslagen.

  • BertS
  • Registratie: September 2004
  • Laatst online: 27-10 13:12
Dat is wel een redelijke conclusie ja ;)

Maar ik ben eigenlijk wel benieuwd hoe je op het idee bent gekomen / wat je redenen zijn om je DAL verwisselbaar te maken?

Verwijderd

BertS schreef op woensdag 31 januari 2007 @ 23:23:
Dat is wel een redelijke conclusie ja ;)

Maar ik ben eigenlijk wel benieuwd hoe je op het idee bent gekomen / wat je redenen zijn om je DAL verwisselbaar te maken?
Het verwisselbaar worden van de DAL is een mooie bijkomstigheid, maar bij complexere queries, krijg je vaak al zoiets als:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public IList Find(object dto, Type t)
        {
            NHibernateManager.Current.OpenSessionInTx();
            ICriteria crit = NHibernateManager.Current.Session.CreateCriteria(t);
            foreach (PropertyInfo pis in t.GetProperties())
            {
                if (pis.Name != "ID")
                {
                    ICriterion criterion = new EqExpression(pis.Name, pis.GetValue(dto, null));
                    crit.Add(criterion);
                }
            }
            IList list = crit.List();
            NHibernateManager.Current.CommitTxAndCloseSession();
            return list;
        }


Zulke code wil je niet in de BLL laag kwijt. Dat zet je in de DAL, daarom leg ik er nog een laagje bovenop, waarin deze stukken code komt te staan, als mede enkele simpele "proxy" methodes voor de Getters, Savers en Deleters, zodat alles uniform benaderbaar blijft.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Sorry, maar zelden zo'n omslachtige manier gezien om een setje entities op te halen. Stel je hebt 10 fields in je entity, dan heb jij 9 compare value predicates in je filter. Verder gebruik je reflection, terwijl je wel de 'ID' field hardcoded in je code hebt, beetje raar.

Ik vind jouw query overigens helemaal niet complex, het is alleen complex opgeschreven.

Maar zijn dit niet gewoon DDD repositories waar jij over praat?

(edit): ik heb nog steeds geen overtuigend argument gehoord waarom je jezelf in dit soort bochten gaat manouvreren... wat WIN je ermee, wat het nadelige effect van extreme complexe code voor iets simpels als een set fetch teniet doet?

[ Voor 21% gewijzigd door EfBe op 01-02-2007 09:45 ]

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


Verwijderd

Topicstarter
BertS schreef op woensdag 31 januari 2007 @ 23:23:
Dat is wel een redelijke conclusie ja ;)

Maar ik ben eigenlijk wel benieuwd hoe je op het idee bent gekomen / wat je redenen zijn om je DAL verwisselbaar te maken?
Ik heb er niet echt redenen voor gehad, het is ook een project voor in de vrije tijd dus ik heb volledige vrijheid. De insteek was een mooie oplossing. Dat wil niet zeggen dat het de beste oplossing is.

Verwijderd

EfBe schreef op donderdag 01 februari 2007 @ 09:37:
Sorry, maar zelden zo'n omslachtige manier gezien om een setje entities op te halen. Stel je hebt 10 fields in je entity, dan heb jij 9 compare value predicates in je filter. Verder gebruik je reflection, terwijl je wel de 'ID' field hardcoded in je code hebt, beetje raar.

Ik vind jouw query overigens helemaal niet complex, het is alleen complex opgeschreven.

Maar zijn dit niet gewoon DDD repositories waar jij over praat?

(edit): ik heb nog steeds geen overtuigend argument gehoord waarom je jezelf in dit soort bochten gaat manouvreren... wat WIN je ermee, wat het nadelige effect van extreme complexe code voor iets simpels als een set fetch teniet doet?
Nee, dat van het ID veld is het enige wat ik inderdaad het mee eens ben. Deze code bouwt een generieke query op die aan de hand van een deels ingevulde DTO de database filtert op de ingevulde waarden, dat gaat je niet lukke op de normale manier.

Heb je een Customer object met de properties: Voornaam, Achternaam, Leeftijd, Woonplaats en je vult alleen leeftijd en woonplaats in, dan zal er een query geproduceerd worden die alle records terug geeft van alle Customers met die leeftijd in die woonplaats. Zou je ook nog de achternaam invullen, dan pakt hij ook nog de achternaam erbij.

[ Voor 16% gewijzigd door Verwijderd op 01-02-2007 13:40 ]

Pagina: 1