[C#] object mapper

Pagina: 1
Acties:

  • zoepercavia
  • Registratie: September 2001
  • Laatst online: 26-12-2025
Uit puur didactisch oogpunt wil ik een object mapper gaan schrijven voor een applicatie. Dit houdt in dat er een object mapping layer komt die weer de persisentence layer aanroept (staat opzich los van de mapping). Ik heb al redelijk wat stukken er over gelezen en heb er ook al een beetje een beeld van. Mijn vraag is alleen hoe concreet te beginnen? Die artikelen schrijven namelijk wel mooi over soorten mapping (vertical, horizontal, etc..) en de theoretische basis (tuples, etc...), maar niet echt hoe zo een laag er uit moet zien. Ik heb al even gekeken naar de demo's van ORM.net (http://www.olero.com)en krijg daar wel een beetje een idee van, maar daar lijken me ook wel wat onhandige dingen in te zitten.
1) er wordt achteraf gefilterd op collections wat me voor de performance niet zo lijkt (hoe kan dit beter?)
2) de laag wil een dsn hebben (een factory pattern lijkt me handiger, dan kan je zelf tenminste je database kiezen)
3) het lijkt er op dat de business logica niet in de objecten zelf kan aangezien de objecten staan gedefinieerd in de gegenereerde laag (het creeeren en vullen van een object door de mapper lijkt me handiger)

Ik had zelf het volgende bedacht (voorbeeldje):

BLL:
class Person
--------------------------
string name
string surname
string initials
string cellularPhone
string workPhone
string homePhone
string fax
string privateEmail
string workEmail
address homeAddress
---------------------------
SavePerson() {
ObjectMapper om = new ObjectMapper();
om.SavePerson(this);
}

OR Mapping:
class ObjectMapper
-------------------------
SavePerson(Person person) {
PersistenceLayer pl = new PersistenceLayer();
pl.SavePerson(person.initials, ...);
pl.SaveAddress(person.address.street, ...);
}

De Persistence layer communiceert dus met de database die er zo uit ziet (maar kan elke willekeurige data opslag zijn):

TblPerson
---------------
string name
string surname
string initials
string cellularPhone
string workPhone
string homePhone
string fax
string privateEmail
string workEmail

TblAddress
-------------------
string street
string number
string city
string country

Nu nogmaals mijn vraag, zit ik op de goede weg, blaat ik complete onzin (ik studeer geen informatica ofzo maar heb wel interesse in gestructureerd programmeren), of is het een beetje klok en klepel idee? En hoe haal ik het beste collections op?

Panacea.NL als je geinteresserd bent in IT en Geneeskunde!


  • whoami
  • Registratie: December 2000
  • Laatst online: 21:46
zoepercavia schreef op 15 April 2003 @ 16:34:
1) er wordt achteraf gefilterd op collections wat me voor de performance niet zo lijkt (hoe kan dit beter?)
Hoe bedoel je, er wordt gefilterd op collections? :?
Waar moeten we dat situeren?
2) de laag wil een dsn hebben (een factory pattern lijkt me handiger, dan kan je zelf tenminste je database kiezen)
Hoe zou je dat verwezenlijken?
Ik heb ooit eens 2 classes geschreven die een connectie met een Database, Sql statements uitvoeren, .... verzorgden in .NET. 1 class voor OleDb en 1 class voor SqlClient. Dmv een abstract factory ging ik daar idd gaan bepalen welke class ik nu uiteindelijk moest maken.
Echter, m'n db-access object verwachte wel nog een DNS. Die is trouwens makkelijk uit te lezen in de web.config in .NET. Ook dit kon wel door middel van de factory gebeuren.
code:
1
2
3
4
5
6
7
8
9
class SqlClientFactory
{

  public SqlDbHelper Create()
  {
      return new SqlDbHelper ( ConfigurationSettings.AppSettings["DataSource"] );
  }

}
3) het lijkt er op dat de business logica niet in de objecten zelf kan aangezien de objecten staan gedefinieerd in de gegenereerde laag (het creeeren en vullen van een object door de mapper lijkt me handiger)
In welke objecten zou je de Business logica zetten?
Ik had zelf het volgende bedacht (voorbeeldje):
Waarom heb je nog een persistence layer? Je kan toch de persistence al doen in je OR layer?

https://fgheysels.github.io/


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Tja, object mapping. In de java wereld kent men veel persistence layers en voor .NET komen er ook steeds meer. Ze hebben zeker voordelen maar ook veel nadelen. Ikzelf ben er nog niet helemaal uit of de voordelen wel tegen de nadelen opwegen, op dit moment zit ik nog in het kamp: ze zijn nadelig.

Mijn grootste reden hiervoor is dat de meeste persistence layers objects maken aan de hand van tables in de database, dus je hebt een 'customer' tabel en dan dus ook een customer object, met properties die velden voorstellen, en methods voor bv het saven van gewijzigde content van het object. Maar in veel gevallen is dit niet een goede, efficiente verdeling om mee te werken op vooral hogere lagen. In veel gevallen wil je met gecombineerde data werken en niet met de objects an sig.

Een voorbeeld:
Stel je hebt een forum systeem en je wilt een thread weergeven op een page, zoals deze page. Als je met een persistence framework werkt, moet je dus message objects ophalen, die moet je in een collection stoppen in een thread object, de messages zijn gepost door users, dus je moet per message een userobject ophalen, een user heeft een usertitle waarschijnlijk opgeslagen in een lookuptable, die moet je dus ook instantieren. Je hebt dus een behoorlijke objecttree.

Nu moet je daar dus efficient doorheen fietsen om deze page op te bouwen. Dat lukt uiteraard wel, maar efficient is het niet. Efficienter was geweest als je een query runt op de database die per ROW 1 message row qua data in zich heeft, dus de message text, de username, de usertitle en nog andere info die nodig zijn voor het displayen van die ene message. Je fietst alle rows van boven naar beneden langs en als je bv dat in een repeater doet ben je zo klaar (ASP.NET).

Persistence frameworks werken je dan dus erg tegen, en dat komt omdat je niet met de objects wilt werken, maar met een view OVER een verzameling objects. Die creeeren aan de hand van een verzameling objects die 1:1 afbeeldingen zijn van entiteiten in de database wordt lastig en is ook inefficient: eerst transformeer je de entiteitdata naar objects, om ze daarna weer uit de objects te halen en samen te nemen. Je kunt dan het gebruik van die objects beter overslaan.

Het is WEL handig, wanneer je individueel met de objects wilt werken, bv je wilt een customer' aanpassen. Dan instantieer je een customer object, die wordt automatisch geladen door de constructor, je modificeert data, roept save aan en klaar. Erg efficient programmeren. Alleen wel in bepaalde gevallen en lang niet in alle (want veel schermen beslaan meerdere objects ipv 1, en dan krijg je dezelfde ellende als hierboven beschreven: vooral bij het vullen van het scherm heb je veel overhead).

Een persistence layer die goed werkt zou dit moeten ondersteunen: ik wil de leverancier ophalen aan de hand van een klant en een order. en een item.

Customers.Customer(iCustomerID).Orders.Order(iOrderID).OrderItems.OrderItem(iOrderItemID).Supplier

Iedere '.' haalt een collectie op uit de database, is dus in feite een stored procedure call. Ik heb nog geen persistence layer gezien die dit genereert. Allemaal proberen ze in bv C# sql na te doen, waardoor je denkt handig bezig te zijn, maar in the end gewoon net zoveel werk doet EN functionaliteit mist, want je bent op de client bezig, dus een aggregate functie aanroepen in je grouped results is er veelal niet bij.

TS: ik zou gaan voor een data access layer die je entiteiten manipuleert en lijsten oplevert (select queries) bij voorkeur in datatables. Daarop bouw je eventueel voor DIE gevallen waar objects als instances van entiteiten makkelijk zijn, een BL facade layer en map je tables op objects. In ANDERE gevallen, zou ik ervoor kiezen om een typed datatable te gebruiken (dat is een van de DataTable derived class waar je columns mapt op properties met een indexer (de row), of een typed dataview.

Heb je niet bar veel tijd, dan zou ik een van de persistence layer generatoren gebruiken, ik weet echter niet of er 1 is die gratis is, de meesten kosten nogal veel geld.

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


  • zoepercavia
  • Registratie: September 2001
  • Laatst online: 26-12-2025
Ik snap denk ik wel wat je bedoelt met het hele overhead probleem. Immers zal je bijna altijd teveel data ophalen (ligt er aan of het een owned of referenced collection is van je entiteit volgens mij). Maar in dit geval gaat het er mij even niet om. Het is niet voor een project voor een klant ofzo, het is puur een projectje om te leren werken met C# en objects (programmeren kan ik wel). Ik wil gewoon wel 's zien hoe het is om puur te programmeren met objects zonder dat je je in principe druk hoeft te maken over de persistence en concurrency.
Ik wil dus gewoon een poging doen om mijn eigen object mapper te schrijven (welke niet eens per se generiek hoeft te zijn, hij mag gewoon lekker specifiek zijn voor mijn object schema). Maar ik moet wel even een beginnetje kunnen maken.
Customers.Customer(iCustomerID).Orders.Order(iOrderID).OrderItems.OrderItem(iOrderItemID).Supplier
, dit lijkt me wel een aardige constructie en zo wil het ook het liefst hebben (ondanks de overhead).

Met de theorie van het factory pattern ben ik bekend en ik wil de persistence en mn mapper loskoppelen omdat je dan een pluggable data layer krijgt. Nogmaals ik weet nog niet of het handig is of nodig, ik wil puur kijken of het kan. Het lijkt me dat de business logic gewoon in de business objects komt, of denk ik nu gek? :)

Nogmaals tijd is het probleem niet, ik schrijf het immers voor me zelf

Panacea.NL als je geinteresserd bent in IT en Geneeskunde!


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Dan is dit echt een dikke aanrader.

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
Hoi

ik ben volop bezig met OJB (het mappen van Java-Objects -> persistant) en ik ga vooledig akkoord met efBE. voor simple dingen is het zalig (echt zalig :)

nee nieuwe user?

User tUser = new User();

store(tUser);

en finito!

maar zoals ie aanhaalt is het verhaaltje al minder leuk als de objecten groter zijn of je wil een gedeeltelijk view op een object hebben. Dan zit je met patatten. Ik heb het 'opgelost' door op een hoger niviau te werken: ie ik werk niet met echt object meer maar gewoon het concept van een object en een property ervan. Door gebruik te maken van een XPath - achtig taaltje kun je dan snel vragen wat je wil , hoeveel je wil zonder problemen. Aangezien het systeem weet waar alles is en hoe het wordt opgeslagen werkt het vlot. Maar OJB vond ik zo handig dat ik het gebruik voor het opslagen van individuele dingen... dus ik map dan mijn objects naar echta javaobjecten en die worden dan door OJB weggeschreven... Maar dat laatste is alleen omdat ik geen tijd had om zelf de nodige querys te generen (wat ie wel doet voor overviews (ie tabular - views)...

het mappen naar echt psysieke objecten vind ik ook een beetje overkill ... je moet alleen het idee van een object hebben en een manier om er tegen te klappen en logica aan te hangen...
Pagina: 1