webForumDet fria alternativet

O/R muppers och uppdatera värden

.NET

14 svar · 687 visningar · startad av Nöff

Medlem sedan nov. 2003569 inlägg
Frågan#1

Låt säga att jag vill uppdatera värdet i kolumnen "namn" i tabellen "kunder" på rad med ID 19. det är ett "int" värde och det ska bara plussas på med 1.

Kan någon beskriva för mig hela programflödet då?. från start(databasen) till det mappade objektet.

Medlem sedan maj 20012 812 inlägg
#2

Nejmen Nöff då! Inte sysslar du väl med O/R Mappers :)

Kan någon beskriva för mig hela programflödet då?.

Du kan inte var lite mer specifik vad du är ute efter. För just programflödet är ju inte så svårt.

1. Hämta ditt kund objekt med ID = 19.
2. Ändrar namnet till vad du.
3. Spara ditt objekt.

Jag misstänker dock att det inte riktigt vad det du var uteefter, om du är uteefter programflödet i O/R Mappern så är det betydligt mer kod, men det finns ju några trådar i ämnet...

- M

Medlem sedan nov. 2003569 inlägg
#3

Nejmen Nöff då! Inte sysslar du väl med O/R Mappers

hehe, nä det gör jag inte.

Men programflödet är nåt sånt här va, för att uppdatera ett värde?:

1. SELECT:a värdet i databasen med en datareader.
2. Fyll objektet med värdet som kom ur databasen.
3. plussa på det ursprungliga värdet i objektet.
4. Läs av objektet och UPDATE:era den underliggande databasen.

Detta lär ju bli en faslig prestandahit eftersom man först måste fylla objektet med den ursprungliga datan.

Medlem sedan maj 20012 812 inlägg
#4

Programflödet är så som du beskriver det.

Detta lär ju bli en faslig prestandahit eftersom man först måste fylla objektet med den ursprungliga datan.

Ja om man utgår från detta exempel, men det är inte så man använder en O/R Mapper.

Säg att du har ett Kundobjekt, och du där i har en kolumn som heter Namn. Och detta kundobjekt har ID = 19.

Det man gör är att man läser in objektet för kunden, prestenterar alla data i en skärmbild och låter sedan användaren ändra namnet och spara sedan ner det igen.

Även om du inte använder dig av en O/R Mapper, så måste du hämta upp informationen från databasen, presenterar den för användaren och sedan spara ner den, så prestandahiten blir inte så krävande som du tror.

Däremot om du har någonsorts av räknare som du ligger och uppdaterar hela tiden så blir det en hit (då du bara vill öka på ett värde i databasen). Men det finns andra lösningar för sådan problem, eftersom man då hämtar objektetn 1 gång och låter sedan detta objekt hanterar räkningen och sedan så updaterar du bara varje gång som man ökat räkningen med 1. Det betyder att det inte blir mer än 1 läsning när du vill använda dig av räkne objektet.

- M

Medlem sedan nov. 2003569 inlägg
#5

men det är inte så man använder en O/R Mapper

Ska man använda O/R mappers måste den klara alla scenarion, annars är det ingen ide.
Man kan inte använda mappern bara för att skapa nya rader i databasen, och sedan tvingas skriva egen kod för att göra mer avancerade saker.

Det man gör är att man läser in objektet för kunden, prestenterar alla data i en skärmbild och låter sedan användaren ändra namnet och spara sedan ner det igen.

Nu utgår du ifrån att det som ska ändras alltid är något man visar på skärmen.
Alla applikationer fungerar inte så.

Om du ska ändra ett värde i databasen måste mappern göra detta:

lite pseudokod:
Customer myCustomer=Mupper.GetCustomer("ID=19");   <---Denna gör en SELECT i databasen för att hämta värdet, och fyller objektet myCustomer med värdet.
myCustomer.namn=e.Item.Cells[3].Text;  <-- ändra värdet i objektet
Mupper.Update(myCustomer);  <--- scanna igenom objektet och slutligen uppdatera databasen med en UPDATE med det nya värdet.

Du måste ju ha tag på objektet innan du kan ändra det. Objektet måste alltid fyllas med det ursprungliga värdet.

Även om du inte använder dig av en O/R Mapper, så måste du hämta upp informationen från databasen, presenterar
den för användaren och sedan spara ner den, så prestandahiten blir inte så krävande som du tror.

Nä det är fel.

myCommand.CommandText="UPDATE kunder SET varde=varde+1 WHERE ID=19";
myCommand.ExecuteNonQuery();

myCommand.CommandText="UPDATE kunder SET namn='hej' WHERE ID=19";
myCommand.ExecuteNonQuery();

För att ändra värdet i databasen direkt utan att först behöva hämta upp värdet.

Och nu utgår du igen att det applikationen ska uppdatera alltid är något man visar på skärmen. Alla applikationer fungerar inte som webshoppar vettu.

Men det finns andra lösningar för sådan problem, eftersom man då hämtar objektetn 1 gång och låter sedan detta objekt hanterar
räkningen och sedan så updaterar du bara varje gång som man ökat räkningen med 1. Det betyder att det inte blir mer än 1 läsning när du
vill använda dig av räkne objektet.

Visa gärna lite kod. Och vilken O/R mapper.

Medlem sedan juli 20011 304 inlägg
#6

Here we go again :)

Programmerar man inte objektorienterat är det ingen större mening med att använda en O/R mapper.

Ska man använda O/R mappers måste den klara alla scenarion, annars är det ingen ide.
Man kan inte använda mappern bara för att skapa nya rader i databasen, och sedan tvingas skriva egen kod för att göra mer avancerade saker.

Varför det? Det går alldeles utmärk att använda en mapper när man programmerar och sedan om man vill göra något speciellt antingen köra som vanligt eller använda mapperns DAL rakt av om den stödjer det.

Hur der gränssnittet ut för det kodexempel du gav?
Hur låter du användare välja att namnet ska bli 'hej' där ID = 19 ? Jo förmodligen så har en användare valt att redigera just det objektet. Jag tvivlar på att då låter dina användare jobba i ett gränssnitt där de bara fyller i ett id och det nya värde som ska sättas eller?

Vill du göra något annat som att plussa på ett värde med ett går det som sagt bra att göra det vid sidan av flödet genom mappern om man nu känner att dessa millisekunder man spara är värda att bryta sin domänmodell.

Men jag vet inte riktigt vad du är ute efter?
Har vi inte redan konstaterat att O/R mappers används för att få en riktig objektorienterad struktur på sin applikation, vilket är viktigt framförallt i seriösa stora applikationer.

Gör man ett litet hack och arbetar proceduriellt behöver man ju inte använda en O/R mapper om man inte är intresserad av att få underhållbarhet och skalbarhet.

Medlem sedan nov. 2003569 inlägg
#7

Varför det? Det går alldeles utmärk att använda en mapper när man programmerar och sedan om man vill göra något speciellt antingen köra som vanligt eller använda mapperns DAL rakt av om den stödjer det.

Varför använda en O/R mapper när den inte klarar av alla steg?.

Hur låter du användare välja att namnet ska bli 'hej' där ID = 19 ? Jo förmodligen så har en användare valt att redigera just det objektet.

Du kommer ändå inte ifrån detta nedan i en webapplikation när du ska uppdatera ett värde:

Customer myCustomer=Mupper.GetCustomer("ID=19");   <---Denna gör en SELECT i databasen för att hämta värdet, och fyller objektet myCustomer med värdet.
myCustomer.namn=e.Item.Cells[3].Text;  <-- ändra värdet i objektet
Mupper.Update(myCustomer);  <--- scanna igenom objektet och slutligen uppdatera databasen med en UPDATE med det nya värdet.

Om du visar lite värden i ett datagrid och användaren ska uppdatera värdena, så kan du kan ju inte bara ta värdet i tex en datagrid och stoppa ner i din O/R mapper, och de objekt du använde för att visa datagridet försvann vid postback, du måste helt enkelt ta upp värdet igen som användare ville ändra ur databasen, fylla objektet igen med värdet, sen ändra objektet, och sen ändra databasen, många onödiga steg. Om du inte håller med får du visa kod på hur du löser det (webforms).

Och nu utgår du också att det som ska uppdateras i databasen är visad på skärmen och är valt specifikt av användaren. Jag sa ju precis att alla applikationer fungerar inte så. Du verkar tala om väldigt enkla applikationer där det bara handlar om ändra data i 1 tabell. Exempel: En applikation där användaren ska spara lite text han skrivit, och detta utlöser en serie av underliggande reaktioner, saker som han inte ser, ska uppdatera 4 tabeller, men först ska dessa värden kalkyleras i applikationen, Och dessa värden som ska uppdateras som användare inte märker av måste ändå alltid hämtas upp ur databasen med en SELECT innan du kan ändra det, denna SELECT behöver inte göras om man inte använder O/R mappers, vissa tabeller har ju över 1 miljon rader, att selectera bara för att uppdatera värden som användaren ändå inte ser kommer smaka prestanda.

Vill du göra något annat som att plussa på ett värde med ett går det som sagt bra att göra det vid sidan av flödet genom mappern om man nu känner att dessa millisekunder man spara är värda att bryta sin domänmodell.

Det handlar ju inte om millisekunder.
Att först visa värdet och låta användaren ändra värdet kommer betyda 2 SELECT:s i databasen, det första när man visar det på skärmen, det andra när man hämtar upp objektet igen för ändring med O/R mappern, när man kunde löst det med 1, Och detta från en tabell med 1 miljon rader kommer ganska effektivt döda prestandan.

Medlem sedan juli 20011 304 inlägg
#8

Varför använda en O/R mapper när den inte klarar av alla steg?.

Förstår inte frågan!?
- varför använda en bil när den inte kan flyga?
Eller det riktiga svaret som jag har skrivit så många så många gånger som inte riktigt verkar gå fram : objktorientering Men självklart tvingar ingen dig att arbeta objektorienterat :)

En fördel med att använda O/R mappern även för vanliga transaktioner är om den innehåller ett kompetent DAL som sköter alla connection, parameters, transaktioner osv åt dig. Du får renare kod och blir databasoberoende.

typ:
DataSet ds = ormapper.ExecuteSQL("Select * from tbl1");
eller
int result = ormapper.ExecuteSQLNonQuery("Insert into tbl1(col1) Values('bleh')");
Nu vet jag inte om alla stödjer detta förfarande ,men den jag jobbar med gör det.

Du kommer ändå inte ifrån detta nedan i en webapplikation när du ska uppdatera ett värde:

Har du aldrig använt dig av en cache?

En applikation där användaren ska spara lite text han skrivit, och detta utlöser en serie av underliggande reaktioner, saker som han inte ser, ska uppdatera 4 tabeller, men först ska dessa värden kalkyleras i applikationen, Och dessa värden som ska uppdateras som användare inte märker av måste ändå alltid hämtas upp ur databasen med en SELECT innan du kan ändra det, denna SELECT behöver inte göras om man inte använder O/R mappers, vissa tabeller har ju över 1 miljon rader, att selectera bara för att uppdatera värden som användaren ändå inte ser kommer smaka prestanda.

I detta fall kanske man väljer att ladda sitt objekt igen (som förmodligen ligger cache:at).

Tror du verkligen att det tar någon mätbar tid att hämta en rad som har en indexerad primärnyckel från en databas, oavsett om det är 1 eller 10000000 rader? Testa så får du se. För du tror väl inte att man går igenom alla rader för att hämta ett objekt?

Det 4 tabellerna är uppmappade och uppdateras automatiskt, är det en avancerad O/R mapper kan du skapa loadgraphs som gör allt i en fråga, dvs inte fler databasanrop än vid manuellt förfarande.

Det handlar ju inte om millisekunder.

Jo.

Och detta från en tabell med 1 miljon rader kommer ganska effektivt döda prestandan.

Nej.

Jag vill verkligen trycka på att själva meningen med en O/R mapper är objekt - relationsdatabas mappning. Det är till för att kunna arbeta med Avancerade metoder för systemdesign, testning och utveckling. Det är för att man ska kunna använda sig av UML, underlätta skalbarhet och underhållsgrad.

Du har rätt i att prestandaförsämringar kan uppstå, men jag anser att du överdriver dem och dess betydelse.

I kommeriella samanhang kan man spara hundratusentals kronor på minskade utvecklingstider, minskat underhåll och skalbarhet.

Medlem sedan maj 20012 812 inlägg
#9

Nöff, det är mycket snack på dig om att programmera olika lösningar och stora lösningar.

Får jag fråga var du jobbar någonstans? Och vilka lösningar som du byggt. För du snackar om: Alla applikationer fungerar inte som webshoppar vettu men samtidigt verkar du inte ha grundläggande kunskaper som caching och hur en databas fungerar.

Så innan vi forsätter debatten så vore det intressant att veta på vilken nivå dina kunskaper ligger och vad du har i ryggsäcken.

- M

Medlem sedan nov. 2003569 inlägg
#10

Har du aldrig använt dig av en cache?

Tänk dig detta: En hierkisk databas, med 7 tabeller i rakt nedåtstigande led.
Varje parent tabell har en trigger som triggar igång kaskader av UPDATE:s
och INSERT:s i SQL-servern. Om du caschar dina objekt, hur ska du kunna veta
vilka rader alla dessa triggers uppdaterade och la in värden i?. och vilka
de nya värdena blev?. det kan du inte med säkerhet vweta, eftersom SqlDependency kommer inte förrän i ADO.NET2.0.
Och så får du gamla cachade objekt som inte stämmer överens med datakällan.
Följdaktligen blir det så att det inte går att cacha starkt volativa data som ständigt förändras. Och då kommer
du ändå att få SELECT:era från databasen för att kunna UPDATE:era data. Det blir alltså 1 onödigt steg i den operationen.

Medlem sedan maj 20012 812 inlägg
#11

Nöff du svarade inte på mina frågor! Gör det först så kan vi diskuterar vidare sedan.

- M

Medlem sedan juli 20011 304 inlägg
#12

Jag vet ine riktigt vad du är ute efter i denna tråd.
Jag tycker att du har ställt en fråga och fått ganska så bra svar, nämligen ungeför hur flödet i en O/R mapper går.

Sedan undrade du över prestandaförluster och fick även där ganska så tydliga svar: det kan uppstå men är inte särskilt stora.

Jag tycker att jag har försökt förklara att det hela här med objekorientering att göra. Det är därför man har skapat O/R mappers. Det finns ingen vits med att dra upp massa exempel som är udda vad det gäller objektorientering och försöka attackera denna teknik utifrån det.

Jag använder inte O/R mapper till allt och inte i alla projekt men när jag gör det så är det för att det är bra.

Vidare känns det lite underligt att du har en så konstig utgångspunkt: att försöka kritisera en teknik och övertyga de som använder den och kan den om att den inte alls är bra, lite som om vi inte skulle veta vad vi håller på med. Detta med utgångspunkt av att du uppenbarligen inte vet hur en O/R mapper fungerar och saknar en del grundläggande kunksaper vad det gäller sql samt inte verkar ha en susning om vad objektorientering är och innebär.

ta inte detta fel nu; du är jättevälkommen med frågor och all teknik ska granskas kritiskt men det kräver en del grundläggande kunskaper för att göra det :)

Medlem sedan nov. 2003569 inlägg
#13

det kan uppstå men är inte särskilt stora.

Klart att det är en rejäl prestandaförlust när du måste selectera data ur
databasen för att kunna förändra dess värde. Istället för att gå direkt mot datakällan.
Och ni säger att man då kan cacha sina objekt som lösning på problemet, men dessa objekt kan du inte
per automatik invalidera om datakällan förändrats (kommer först i ADO.NET2.0).
Så var cachningslösningen en sån lysande ide där eller?..
Och vad fick jag för svar?. En massa ifrågasättande om min person istället, vad har det med saken att göra?.

utgångspunkt av att du uppenbarligen inte vet hur en O/R mapper fungerar

Förklara var jag hade fel i min förklaring hur en O/R mapper gör för att uppdatera ett värde i databasen.

samt inte verkar ha en susning om vad objektorientering är och innebär

Vad i min text baserar du det på?.

Jag tycker att jag har försökt förklara att det hela här med objekorientering att göra.
Det är därför man har skapat O/R mappers. Det finns ingen vits med att dra upp massa
exempel som är udda vad det gäller objektorientering och försöka attackera denna teknik utifrån det.

Var har jag skrivit att objektorienterade lösningar för att komma åt databasen är en dålig ide?.

Medlem sedan maj 20012 812 inlägg
#14

En massa ifrågasättande om min person istället, vad har det med saken att göra?.

Det är ingen som ifågasätter dig som person, bara din kunskap inom området. Du har fått svar på ditt PM om mina förundringar.

Okej, jag skall bemöta dina påstående/argument..

För det första så är det ingen större skillnad hur ett DataSet och en ORMapper används för att fylla data. Båda hämtar data från databasen och lagrar dessa i objekt. ORMappern skapar specifika objekt för varje data, medans DataSet lagar datan i ett specifik object, dataRow.

Ska man använda O/R mappers måste den klara alla scenarion, annars är det ingen ide.

En ORMapper är perdefinition menat till att hantera så som att En tabell är Ett objekt, alltså det finns en direkt koppling mellan tabellen och objektet, detta gör den lämpligt att använda i vissa situationer medans direkt olämplig i andra. Alltså så använder man inte en ORMapper i alla lägen. Ex: Är man endast intresserad av att presentera data på en websida, så är en DataReader och en Repeater ett bättre och smartare val ur prestandasynpunkt, ur underhållssynpunkt och skalbarhetsynpunkt så kan en ORMapper vara bättre. Så nej en ORMapper måste inte kunna allt, då blir den mest generell och långsam som dataset.

ändå alltid hämtas upp ur databasen med en SELECT innan du kan ändra det,

Din syn på vad en ORMapper kan göra och inte göra är lite konstig, du påstår att man måste göra en SELECT för att göra en update. Ditt finns ORMappers som kan (precis som Jon sa) exekvera standard SQL rakt av om man önskar. Skulle jag ha behov av att köra en UPDATE utan att först göra en SELECT (typ A = A + 1, kommandot) så kan jag enkelt lägga till den funktionallitetn i min ORMapper, och vips så kan jag gör UPDATEN genom att skapa ett objekt, sätta ID = 19 och välja ett fält (kolumn) och sedan sätt en enum till Incresse. När jag sedan spara mitt objekt, så kommer min ORMapper finna ut att jag vill endast göra en incresse på ett fält till en tabel med ID = 19. Och då generera SQLkoden: UPDATE [kund] SET [Count] = [Count] +1 WHERE [Identifier] = 19, då fungerar min ORMapper på det sättet som du säger att den inte kan. Är det så att det inte är en räknar vi är uteefter utan endast uppdatera namet utifrån ID utan att ha presenterat datan, så kan man lösa det med att endast göra förändringar på fält som är ändrade, man tar alltså en snabbshot av hur datan såg ut ibörjan (typ allt är null) och sedan så jämför man med ur datan ser ut när man gör sin save och bygger en UPDATE sql sats utifrån det.

och de objekt du använde för att visa datagridet försvann vid postback, du måste helt enkelt ta upp värdet igen som användare ville ändra ur databasen

Hmmm... Okej säg nu att min ORMapper inte klara av att göra en UPDATE direkt. Jag läser först upp data till mitt objekt, visar data på sidan och sedan göra en postback. Varför skulle jag inte kunna lägga mitt objekt i Session och sedan använda det för att göra en save i min postback, eller som datasetet gör, lägga en serializerat objekt i viewstaten och sedan vid postbacken deserializera tillbaka mitt objekt och sedan göra en save. Så nej jag måste inte göra en SELECT igen för att hämta värdena, jag har valmöjligheten att göra det, eller att lägga objektet i en session, eller en egen cache, eller i viewstaten. Med ditt dataset så har du samma möjlighet att behålla data vid en postback.

En applikation där användaren ska spara lite text han skrivit, och detta utlöser en serie av underliggande reaktioner, saker som han inte ser, ska uppdatera 4 tabeller, men först ska dessa värden kalkyleras i applikationen, Och dessa värden som ska uppdateras som användare inte märker av måste ändå alltid hämtas upp ur databasen med en SELECT innan du kan ändra det, denna SELECT behöver inte göras om man inte använder O/R mappers

Nu förstår jag verkligen inte vad du menar, menar du att om man använder en ORMapper så måste man först hämta alla data med en SELECT och sedan använder man denna data för underliggande kod, och tillslut så uppdatera man i tabellerna. Jag kan inte se hur du skulle kunna lösa det på något annat sätt med ett DataSet, du måste hämta samma data som jag gör med min ORMapper eftersom den behövs vid beräkningarna. Möjligvis så menar du att man spara data till andra tabeller där man inte har hämtat data sedan tidigare och då påstår du att jag måste hämta datan med en SELECT först medans med ett DATASET så kan man göra en UPDATE direkt, så fall refererar jag till ovanstående text där den myten dog.

Det handlar ju inte om millisekunder.

Faktiskt så handlar det om millisekunder, allt beroende på hur din databas ser ut, men att lägga 1 miljon rader i en SQLdatabas är inget som den får skrämselhicka av, har jobbat med databaser som har haft upp mot 15 miljoner rader kod, och en rätt indexerad databas hämtar ut den datan på under sekunden, svårt att säga tid då QA inte har så bra tidsangivelse. Sedan är det också så att exekveringsplanen för en SELECT statement sparas så nästa gång så går det ännu fortare.

Tänk dig detta: En hierkisk databas, med 7 tabeller i rakt nedåtstigande led

Helst inte, hade prylat min dba om han hade gett mig en sådan databasstruktur...

Varje parent tabell har en trigger som triggar igång kaskader av UPDATE:s
och INSERT:s i SQL-servern. Om du caschar dina objekt, hur ska du kunna veta
vilka rader alla dessa triggers uppdaterade och la in värden i?. och vilka
de nya värdena blev?.

I det läget så kan du inte ha data cachade eftersom datan ändras utan för ORMappern vilket betyder att datan i ORMappern och datan i databasen inte kommer att vara samma. Lösningen är att låta ORMappern sköta det jobbet som trigger gör. Man skriver helt enkelt in kod i sina objekt som skall utföras som en trigger, på det visset så kommer den cachade datan vara samma som i databasen.

Det undrar mig dock att du tog upp det exemplet eftersom det knappast blir bättre med ett dataset, den datan som du har i datasetet är också inaktuell när triggersna slår igenom och man måste hämta datan igen, så varför exemplet?

Klart att det är en rejäl prestandaförlust när du måste selectera data ur
databasen för att kunna förändra dess värde. Istället för att gå direkt mot datakällan.

Definera en rejäl prestandaförlust och definera vad du skall göra med datan, om det är en weblösning, så ligger inte prestandahiten vid en select i databasen utan vid transport av data till och från klienten. Helt beroende på miljöer så kan det röra sig om skillnader på 100:1 alltså knappast lönt att lägga tid på att fixa, men som sagts tidigare det handlar om millisekunder för att hämta ut värde ur en databas.

Och ni säger att man då kan cacha sina objekt som lösning på problemet, men dessa objekt kan du inte
per automatik invalidera om datakällan förändrats (kommer först i ADO.NET2.0).

Återigen så ligger fokus på felställe, när Jon föreslog cachen så handlade det om slippa hämta data från databasen vid en postback, vilket du hävdare att man måste, vilket jag tog död på högre upp i texten. Om man använder sig av den cachade datan så behövs endast 1 SELECT, precis som med ett DataSet eftersom datan skall presenteras först. Skall det var så att datan inte skall presenteras först så har jag gett förslag på lösningar för att göra en UPDATE mot databasen direkt ovan.
Handlar det om en vanlig cache så kommer även ett DataSets data att bli inaktuell vid förändringar i databasen som inte går genom datasetet.

Förklara var jag hade fel i min förklaring hur en O/R mapper gör för att uppdatera ett värde i databasen.

Du hade inte fel, bara att du inte tagit med alla möjligheter, många ORMappers gör en SELECT - Ändra - UPDATE, bara att man inte måste det. Det går lika bara att: Ändra - UPDATE om man nu har den funktionallitetn i sin ORMapper eller skriver det själv.

Men som Jon sa: vad är du ute efter egentilligen, vill du använda DataSet så gör det, ingen tvingar dig till något annat. Du måste dock förstå att det finns en större värld utan för ditt fönster och alla kommer inte följa dina råd och vägar. I många projekt som jag varit med i så använder vi oss av webservices, och just till webservices så är dataset riktigt korkade att använda, då man tvingar klienten till att vara en .NET klient och i vår miljö så har vi flera olika plattformar: Java, notes, cobol... så där fungera en ORMapper ypperligt: Ladda ORMappern med data och sedan tar man ormapper.GetArray() så har man fått en array av objekt som vem som helst kan hantera och inte nog med det man får en objektorienterad lösning över webservicen på multiplaplattformar, inget som ett dataset klara av.

- Magnus

Medlem sedan juli 20011 304 inlägg
#15

En massa ifrågasättande om min person istället, vad har det med saken att göra?

Absolut inte min mening att angripa dig som person! Ta det inte så. Håller inte med dig bara och en del av dina argument är ganska så malplacerade vilket föranleder mig att tvivla en del på grunden för dom bara.

278 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
120 ms — deklarationer (db)
0 ms — hämta statistik (cache)
149 ms — hämta tråd, inlägg och bilagor (db)
124 ms — ändringar (db)