Vedvarende avledet attributes

Et lite eksempel på å lage avledede attributter som vedvarte til database.Persistent avledet attributter i BoldBold er avledet attributter evalueres alltid i minnet, og dette gjør det umulig å utføre en INPS (persistens lagring) søk mot visse data. Enhver søk uttrykk som refererer til en avledet attributt vil føre Fet å laste alle objekter fra databasen i minnet først for en in-memory evalution, kan dette være svært treg og ressurs consuming.Past diskusjoner har blitt lagt ut på støttegrupper spørre hvordan oppnå avledet attributter som også vedvarte til DB for SQL evaluering. I dag hadde jeg det samme kravet, og dette er den løsningen jeg kom opp with.The første du må gjøre er å unngå å markere attributt som utledet i modellen. I stedet gjør attributt en vedvarende attributt, for eksempel Fullname: string (128)
Det neste trinnet er å sikre at verdien av Fullname er alltid oppdatert, så vi trenger å overstyre ReceiveEventFromOwned i hvert kommer klasse vi skape
prosedyre
TPerson.ReceiveEventFromOwned ((Opphavsmann:. TObject; OriginalEvent: TBoldEvent); begynne
arvet
; hvis plakater (OriginalEvent = beCompleteModify) og plakater (Opphavsmann = M_Name) deretter
Fullname: = M_FirstName.AsString + '' + M_LastName.AsString; end
;
Dette vil sikre at attributtet er alltid oppdatert, men svakheten her, som vi vil nå ta opp, er at det er mulig å endre Fullname manuelt. For å løse dette problemet må vi gjøre Fullname beskyttet, som så
funksjon
TPerson.ReceiveQueryFromOwned (Opphavsmann: TObject; OriginalEvent: TBoldEvent, const args: array of const; Subscriber: TBoldSubscriber): Boolean; begynne
Resultat: = arvet
ReceiveQueryFromOwned (Opphavsmann, OriginalEvent, args, Subscriber); hvis ikke
Resultat eller
BoldObjectIsDeleted deretter
Exit; hvis plakater (Opphavsmann = M_FullName) og plakater (OriginalEvent = bqMayModify) deretter
begynne
Resultat: = False; //Uventet feil SetBoldLastFailureReason (TBoldFailureReason.Create ('Fullname er uforanderlig', Selv)); end
; end
;
Fullname kan nå ikke lenger endres, dessverre feilen vi har innført, er at vi ikke lenger kan sette verdien av Fullname i vår avledning code.To løse dette siste problemet vi trenger en måte å identifisere brukeren /normal-kodeendringer og "interne" endringer. For å gjøre dette jeg alltid implementere et felles mønster til min base objekt, som so1) Lag en Delphi attributt - InternalChangeCount: integer2) Legg en beskyttet metode BeginInternalChange3) Legg en beskyttet metode EndInternalChange4) Legg et beskyttet metode IsInternalChange: Boolean
//Merk: TRootObject er roten gjenstand for min modell prosedyre
TRootObject.BeginInternalChange; begynne
Inc (fInternalChangeCount); end
; prosedyre
TRootObject. EndInternalChange; begynne
hvis
fInternalChangeCount = 0 deretter
heve
Exception.Create ('EndInternalChange uten BeginInternalChange'); DEC (fInternalChangeCount); end
; funksjon
TRootObject.IsInternalChange: Boolean; begynne
Resultat: = (InternalChangeCount > 0); end Anmeldelser;
slutt, vi trenger bare å oppdatere den originale kildekoden så that1) Innstilling av avledet kode er gjort innenfor en "intern endring" 2) Endringer Fullname er tillatt dersom endringen er en intern en
prosedyre
TPerson.ReceiveEventFromOwned (Opphavsmann: TObject; OriginalEvent: TBoldEvent); begynne
arvet
; hvis
OriginalEvent = beCompleteModify deretter
begynne
hvis plakater (Opphavsmann = M_FirstName) eller plakater (Opphavsmann = M_LastName) deretter
prøve
BeginInternalChange; Fullname: = M_FirstName.AsString + '' + M_LastName.AsString; endelig
EndInternalChange; end
; end
; end
; funksjon
TPerson.ReceiveQueryFromOwned (Opphavsmann: TObject; OriginalEvent: TBoldEvent; const args: array of const; Abonnent: TBoldSubscriber): boolske; < b> begynne
Resultat: = arvet
ReceiveQueryFromOwned (Opphavsmann, OriginalEvent, args, Subscriber); hvis ikke
Resultat eller
BoldObjectIsDeleted deretter
Exit; hvis plakater (Opphavsmann = M_FullName) og plakater (OriginalEvent = bqMayModify) deretter
begynne
hvis
IsInternalChange deretter
Resultat: = True annet
Resultat: = False; //Uventet feil hvis ikke
Resultat deretter SetBoldLastFailureReason (TBoldFailureReason.Create ('Fullname er uforanderlig', Selv)); end
; end
;
I søknaden Jeg skaper objektet strukturen er faktisk som følger: RootObject (ModelRoot) RoledObject (Har en Fullname) Person (Fullname = Fornavn + ' '+ Lastname) Institutt (Fullname = Navn) Company (Fullname = Navn) Konklusjon: Denne teknikken krever bare en liten del av koden for hver kommer klasse (RecevieEventFromOwned) samtidig som evnen til å utføre søk på DB server mot en avledet attributt. Jeg føler at fordelene i stor grad oppveie den lille mengden av arbeid som er nødvendig for å oppnå dem. Anmeldelser