webForumDet fria alternativet

NHibernate och id:en.

.NETur .NET

10 svar · 613 visningar · startad av Gladh

Medlem sedan maj 20012 812 inlägg
Frågan#1

Jag hade tänkt att byta ut min egen lilla ORM mot NHibernate och springer rakt in i väggen direkt.

Följande är scenariot.
Jag har en klient och en Services. Klienten skall kunna fungerar även om den är offline, vilket gör följande. Säg att klienten är offline och jag skapar en kund, denna kund vill jag sedan använda till en order som jag även skapar medans systemet är offline. För att binda ihop ordern och kunden så sätter jag ett kundid på ordern, och i och med det så måste jag ju skapa ett id för kunden ute på klienten, alltså så sätts kundid redan ute på klienten.

När klienten sedan blir online så skickas denna informationen till services som nu skall skriva ner detta till databasen. Problemet här blir då att eftersom id:et redan är satt så tror NHibernate att kunden redan finns i databasen och vill göra en UPDATE istället för en INSERT.

Hur löser jag detta, så att NHibernate kontrollerar ett annat värde än just ett tomt GUID för att kontrollera om posten finns i databasen eller ej...

En riktigt fullösning vore att ha ett Identity fält i databasen som är en räknare och den kommer ju vara 0 tills det är satt i databasen och inget som mina program någonsin kommer ändra, men det är ju ett riktigt FULHACK, så jag hoppas på något enklare sätt. Typ att jag har en boolean som är true om det är ett nytt objekt och false om det är ett objekt från databasen, men hur kopplar jag det till NHIbernate så den förstår om den skall välja INSERT eller UPDATE.

- M

Medlem sedan aug. 20003 575 inlägg
#2

Eftersom du har valt strategin med GUID, kan du inte när du går ifrån ett offline läge veta om vilka objekt som inte är nersparade.

Alternativ två vilket antagligen är det bästa är att sätta alla osparade id:n till en empty guid dvs {0000-0000..... sedan kan du mappningen säga att det är en nytt entitet som skall sparas ner om id:t är {0000-0000

Hoppas mina svar hjälper dig.

Sessionen har 3 spara val.

SaveOrUpdate som låter NHibernate avgöra om objektet är nytt eller ej.
Save sparar objektet som nytt. -> Insert
Update uppdaterar objektet. -> Update

Medlem sedan maj 20012 812 inlägg
#3

nickemannen skrev:

Alternativ två vilket antagligen är det bästa är att sätta alla osparade id:n till en empty guid dvs {0000-0000..... sedan kan du mappningen säga att det är en nytt entitet som skall sparas ner om id:t är {0000-0000

Problemet är att jag behöver id:et i min offline klient för att kunna knuta ihop relationer mellan olika objekt.

Bara för att komplicera det ännu mer så kan jag inte spara ner objektet och använda mig av den relationen utan det måste vara id. Jobbigt att förklara men så är det bara... :)

Och precis som du säger, så när jag väl skickar mitt objekt från min klient till min services så kan inte servicen se på id:et om det är ett nytt objekt eller ett gammalt som måste sparas.

Så det verkar som jag har 2 val bara...

1. Lägga till en identity kolumn i databasen som endast har som uppgift att kontrollera om objektet är spara eller ej.
2. Skicka med en boolean som flaggar om objektet är nytt eller gammalt och utifrån det så måste jag välja Save eller Update...

Inget är bra men det lutar nog åt alternativ 1, mindre kod för mig att skriva men lite "skitigare databas".

- M

Medlem sedan aug. 20003 575 inlägg
#4

hmm, okej tråkigt att du behöver id:t antar att det är nödvändigt att ha id:t och inte köra med objektreferenser istället?

Ett tredje alternativ skulle vara att lagra de objekt eller som är nya i en createdWhileOffline list som du går igenom det första du gör när du kopplar upp dig och sparar som nya objekt.

På det sättet fortsätter dina objekt vara persistence Ignorant :).

Medlem sedan juni 20003 076 inlägg
#5

Kan du inte bara jämföra ditt id från klienten med databasen när den kommer online, finns inte id:t så betyder det att det är en ny kund och du kör då en insert.

Medlem sedan maj 20012 812 inlägg
#6

doggelito skrev:

Ett tredje alternativ skulle vara att lagra de objekt eller som är nya i en createdWhileOffline list som du går igenom det första du gör när du kopplar upp dig och sparar som nya objekt.

Problemet är ju att när objekten kommer till servicen, så har den ingen anning om att de kommit från en "createdWhileOffline" lista, och då måste ju jag implementera någon lösning som berättar för servicen om det är ett nytt objekt eller ej...

doggelito skrev:

Kan du inte bara jämföra ditt id från klienten med databasen när den kommer online, finns inte id:t så betyder det att det är en ny kund och du kör då en insert.

Visst kan jag göra det, men varför skall jag göra det, jag vill ju minimera min kod och låta ORMappern sköta sådant åt mig...

I min egen ORM så löste jag det på följande vis. Jag skapade ett Identifier-objekt som kunde innehålla både en GUID eller en INT, när man skapad en ny identifier som en guid så sattes en flaga i Identifier-objektet att det var ett nytt objekt, så även om identifier hade ett värde så sa flaggan att objektet var nytt. När man hämtade objekten från databasen så markerades objektet som gammalt och ORM visst då att det skulle vara en UPDATE och inte en INSERT för detta objekt. Smidigt men inte helt PI ;)

- M

Medlem sedan aug. 20003 575 inlägg
#7

Gladh skrev:

doggelito skrev:

I min egen ORM så löste jag det på följande vis. Jag skapade ett Identifier-objekt som kunde innehålla både en GUID eller en INT, när man skapad en ny identifier som en guid så sattes en flaga i Identifier-objektet att det var ett nytt objekt, så även om identifier hade ett värde så sa flaggan att objektet var nytt. När man hämtade objekten från databasen så markerades objektet som gammalt och ORM visst då att det skulle vara en UPDATE och inte en INSERT för detta objekt. Smidigt men inte helt PI ;)
- M

Det går att lösa det på ett liknande sätt i NHibernate :), men som du säger inte helt klockrent.

Annars låter det dock som en omöjlig uppgift om du inte vill ändra ditt service interface så att den har en Save och en Update istället för enbart en SaveOrUpdate typ. :) För på något sätt måste ju objektet på något sätt markeras eller finnas i någon lista.

Medlem sedan okt. 200850 inlägg
#8

Kan du inte skapa din kund först och sedan låta din order bli updaterad.. Skapa en Fasad som tar emot din order och kund och ser till att först lägga till kunden, sedan spara din order.. KISS!

Medlem sedan maj 20012 812 inlägg
#9

fredrikn skrev:

Kan du inte skapa din kund först och sedan låta din order bli updaterad

Problemet är att både kunden och ordern (eller vad det nu är för något, artikel, transport info osv osv..) kan skapas när klienten är offline. Och jag måste då knuta ihop kunden och ordern, och eftersom det måste göras med ID och inte med objektet så måste jag skapa ID ute på klienten.

När sedan klienten gå online så skall kunden och orden skickas till servicen och då sparas ner till databasen, och eftersom deras ID redan har fått ett värde, så kan jag inte låta NHibernate titta efter ett tomt guid... :(

Jag tror att smidigaste lösningen blir att jag bara slänger på ett identity fält på tabellen och när det är 0 så är måste man göra en INSERT och har den ett annat värde så blir det en UPDATE, medans jag själv fortsätter att använda GUID:en som referenser mellan objekten.

- M

Medlem sedan aug. 20003 575 inlägg
#10

Gladh skrev:

fredrikn skrev:

Kan du inte skapa din kund först och sedan låta din order bli updaterad

Problemet är att både kunden och ordern (eller vad det nu är för något, artikel, transport info osv osv..) kan skapas när klienten är offline. Och jag måste då knuta ihop kunden och ordern, och eftersom det måste göras med ID och inte med objektet så måste jag skapa ID ute på klienten.

När sedan klienten gå online så skall kunden och orden skickas till servicen och då sparas ner till databasen, och eftersom deras ID redan har fått ett värde, så kan jag inte låta NHibernate titta efter ett tomt guid... :(

Jag tror att smidigaste lösningen blir att jag bara slänger på ett identity fält på tabellen och när det är 0 så är måste man göra en INSERT och har den ett annat värde så blir det en UPDATE, medans jag själv fortsätter att använda GUID:en som referenser mellan objekten.

- M

Varför måste du knyta ihop ordern och kunden med id:n?

Medlem sedan maj 20012 812 inlägg
#11

nickemannen skrev:

Varför måste du knyta ihop ordern och kunden med id:n?

Nu gäller det inte just order och kunder utan andra objekt (dessa 2 var bara exempel) det är lite jobbigt att förklara men tro mig det fungerar inte med objektrelationer eftersom jag kommer ha 2 olika objekt som kommer se exakt likadana ut för användaren, och om användare gör förändringar i det ena objektet så kommer de 2 objekten att se olika ut, vilket användaren inte förväntar sig.

Och det beror på att alla objekt hämtas från en services och skickas till klienten, så även om det skulle vara exakt samma objekt i services så kommer det bli 2 olika objekt på klienten...

- M

135 ms totalt · 3 externa anrop · v20260731065814-full.b746b907
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
132 ms — hämta tråd, inlägg och bilagor (db)