Hur gör ni om ni har ett rot objekt som har exempelvis 20 under objekt. Dessa objekt spänner över 20 tabeller i databasen. Hur skulle ni göra den uppdateringen mot databasen (anropet kommer till en webservice)? DataSets är förbjudet i den här lösningen. Din fråga gäller fortfarande bara hur själva uppdateringen skall gå till, eller hur? Även om du använder webservices eller ej. Tack för svaret!! Tjenare ! "Som vi löst problemet så cachar vi rot objektet innan vi skickar tillbaka det till klienten. När objektet kommer tillbaks till servern går vi igenom objektet och jämför med orginalet med reflection." Tjenare! "Du vill inte ta bort all data och lägga till den igen. Inte i vårt fall iallafall. uppdatering av stort objekt
Som vi löst problemet så cachar vi rot objektet innan vi skickar tillbaka det till klienten. När objektet kommer tillbaks till servern går vi igenom objektet och jämför med orginalet med reflection.Vi jämför genom att sträng konkatenera alla fält och tar en hashkod på den strängen. Det är detta hash värdet som vi jämför varje objekt på orginalet med det uppdaterade. Utav denna jämförelse kan vi dra slutsen om vilka objekt som är nya, uppdaterade eller borttagna.Uppdateringen av databasen sker då alltså bara med dessa modifierade objekt.
Kommentera gärna :-) såga min metod mer än gärna :-) Sv: uppdatering av stort objekt
Jag skulle försöka ha en databasklass där rotobjektet ligger under, och från denna databasklass starta en transaktion som alla underliggade uppdateringar kommer att använda sig av.
Sedan skulle jag hierariskt iterera genom alla uppdateringar, uppifrån och ner. (Alla objekt har sin Update() funktion.
Exempel:
RotObjekt.Update (uppdaterar sin tabell med värden. Samt att att varje Kund i RotObjekt.Kundlista har sin updatefunktion som uppdaterar först sin tabell, och sedan itererar genom update för alla underliggande personer.)
Osv osv. Smäller det nånstans rulla tillbaka och berätta varför det small.
DatabasObjekt -skapa transaktion härifrån, om det finns fler rotobjekt
'- RotObjekt
'-ListaKunder
'-Kund1
'-Person1
'-ListaFakturor
'-Etc
Och ang. comparefunktionen - Vi har en liknande Clone funktion för att spara ner objektet innan förändring, men det kan också bli prestandaproblem om det är många objekt, och om objekten har många sublistor, som har sina sublistor, etc etc. I slutändan jämförde vi bara egenskap för egenskap i en HasChanges funktion.
(allt detta är då genererat från egenskriven datalager/affärdslager generator)Sv:uppdatering av stort objekt
Anledningen till att jag skrev webservices var att markera att objektet inte lever i samma app domain hela tiden, vilket gör att man inte har att göra med samma instans av objektet när det kommer tillbaka för uppdatering. Men givetvis är det samma problematik som gäller.
Japps, det låter som en bra lösning.
Jag har dock några invändningar.
Update metoden fungerar väl bara om objektet fanns från början om det är tillagt eller borttaget, hur fungerar det då? Jag glömde skriva i den lösningen som vi gjort har varje objekt ett unikt id vilket används till att kolla ifall objektet är uppdaterat, borttaget eller tillagt.
Ifall du delegerar update metoden till varje enskilt objekt får du svårt att uppdatera databasen ifall objekt/domän modellen inte stämmer överrens med databasen.
HasChanges låter ju helt klart som en bra lösning men via reflection får man en mer generisk lösning som gör att man slipper skriva samma kod om och om igen.
Clone metoden. Hur gör ni den *nyfiken*? Vi serialiserar/deserialiserar objektet.Sv: uppdatering av stort objekt
Jo eftersom du bara skickar tillbaka en modifierad kopia av objektet (om jag förstått det rätt) så skulle man kunna lägga till ett par listor som berättar vad som ska hända med objekten. Sedan vid den "stora" updatefunktionen så går den igenom alla listor och utför lämplig händelse.
Ang. Clone, så stötte vi på ett hyfsat stort prestandaproblem. Från början så gjorde vi precis samma sak, serialiserar objektet och deserialiserar det fram till en ny instans av objektet i fråga. Och alla sublistor och alla dess sublistor och egenskaper följer med. Kanon! Men om man bara vill ha egenskaperna från vars objekt man är på just nu vill man inte ha med sublistorna. Använder man clone hejvilt (vilket vi gjorde vi Comparefunktion etc) Och Comparefunktionen använde vi vid HasChanges funktionen. Inte så smart mao så applikationen blev jätteslö snabbt :/
Så vi gjorde om Clone till Copy istället, vilket struntar i sublistor med objekt, och bara klonar till en ny instans av objektet. Kör man HasChanges, körs Compare, och då körs Clone. Lite rörigt och svårt att förklara utan att rita upp objektmodellen, men jag hoppas du förstår =)
Och vi skrev allting i en egengjord klassgenerator, så att generera en klass tar en sekund, så då slipper man manuellt sitta och fylla i allting i Clone och andra funktioner.
Jag gillar tekniken din jämförelsefunktion, den tänker jag sno =) Hur var det du gjorde, du lade ihop alla egenskaper till en sträng och hashar den, och sparar i en variabel typ OriginalValues ? Vi gör på liknande sätt men inte med hashad konkatenerad sträng men det låter smartare.Sv: uppdatering av stort objekt
Lite nyfiken. Du skickar alltså tillbaka hela "rot-objektet" till servern och där gör du en kontroll om något har ändrats, och om det har det så ändrar du i databasen, om inte så förkastar du bara objektet?
Låter lite som du silar mygg och sväljer kameler :)
Att göra en updatering i databasen på icke ändrade objekt är inte alls så prestanda krävande som att skicka objekten över en webservice. Så här hade jag prioriterat att lösa det.
1. Skicka allt och spara allt.
2. Gör en funktion på klient sidan som kontrollerar om det har skett något med objektet och om det inte skett något så skickat inte till serven.
3. Gör samma kontroll på servern om det visar sig att klientprogrammeraren är en klåpare som inte gör som sagt, samt att flaskhalsen ligger hos databasen och inte på serven (det tar ju faktiskt lite prestanda att göra kontrollerna)
Sedan har du ett annat problem och det är vilka ändringar som skall gälla egentligen..
Säg att du har 2 klienter som läser samma objekt och båda två ändrar objektet men med olika data. Vilken data är det då som skall gälla, är det den data som kommer sist, eller skall det varnars om att datan är ändrar sedan man läste upp den?
Där ser jag en vinst i att ha objektet (egentligen behövs inte hela objektet, bara en lastmodified egenskap) cachat på server sidan så man slipper gå ner till databasen för att kontrollera att någon annan har ändrat datan mellan att jag laddat och vill spara mitt objekt
Problemet med denna lösning blir att mitt förslag med med att lägga kontrollen på klienten kan förstöra datan, det kan ju faktiskt var den korrekta lösningen som skall skrivas även om man inte ändrat något i den, men kontrollen på klient gör att den aldrig skickas till serven...
- MSv:uppdatering av stort objekt
"Lite nyfiken. Du skickar alltså tillbaka hela "rot-objektet" till servern och där gör du en kontroll om något har ändrats, och om det har det så ändrar du i databasen, om inte så förkastar du bara objektet? "
Japps.
Du vill inte ta bort all data och lägga till den igen. Inte i vårt fall iallafall.
En fråga: Hur skulle du kunna fånga upp ett borttaget objekt och ta bort det från databasen? Det kan bli en aning svårt i vissa fall om man saknar idet.
I en webservice är det en aning svårt att ha koll på vad klienten gör. :-)
Jag kan hålla med om att en av svagheterna ligger i cachningen och att data kan skrivas över. Men eftersom datan är personberoende så uppstår bara problemet om klienten har två inloggningar. Vi har en LastUpdated på rot objekt som uppdateras varje gång en ändring sker. Det kanske är läge att införa en koll på att det inkommande och det cachade objekt har samma tidsstämpel, än så länge släpper vi bara igenom det.Sv: uppdatering av stort objekt
En fråga: Hur skulle du kunna fånga upp ett borttaget objekt och ta bort det från databasen? Det kan bli en aning svårt i vissa fall om man saknar idet.
I en webservice är det en aning svårt att ha koll på vad klienten gör. :-) "
Du har helt rätt i att det är svårt för webservicen att veta vad klienten gör, men det är inte det jag syftar på, jag syftar på att den logik som ligger i webservicen (för att kontrollera om något har hänt med objektet) skall flyttas ut på klienten istället, för om inget har hänt med objektet så finns det ingen mening att det skickas till webservicen, eftersom servicen inte skall göra något med objektet.
Så den enda skillnaden blir att kontrollen ligger på klienten och du får mindre nätverkstrafik och därmed bättre prestanda... :)
- M