Læse data fra tabeller (SqlDataReader) på en sikker måde
Jeg stammer fra Delphi-verdenen og dette indlæg er et undrende hjertesuk.Nu er det C# og jeg savner et ordentligt programmeringssprog! Specifikt leder jeg efter samme funktionalitet som jeg havde tidligere, for det gav sikker kodning.
{
ref int not null
,postnr nvarchar(10) not null
,postby nvarchar(50) not null
}
select ref
,postnr
,postby
from dbo.postnrtabel
I Delphi kan man lægge scriptet ind i en TQuery (TADOQuery)-komponent, her kaldet qPostnrTabel. Forbinde til en base. Dobbeltklikke på komponenten og vælge de tre felter. Hermed blev der lavet 3 felt-linjer: qPostnrtabelRef: TIntegerField, qPostnrtabelPostnr: TStringField, qPostnrtabelPostBy TStringField; I koden refererede man direkte til disse, eks. Ref := qPostnrTabelRef.AsInteger;
Man kunne naturligvis også bruge qPostnrTabel.FieldByName(<feltnavn>) og qPostnrTabel[<feltnavn>] ... men det prøvede man at undgå.
Det gav en stor sikkerhed i programmeringen, fremfor SqlDataReaders reader.GetInt32(0) og GetString(1) og GetString(2). Noget lort hvis jeg rekreerer tabellen og tilføjer en aktiv-bit efter ref-feltet i tabellen, eller fjerner et felt i den. Så skal jeg HUSKE at rette længere nede. Programmet oversætter fint uanset dette. Jeg kan også skrive (int)reader["ref"] osv, men hvis jeg vælger at ændre postby til by, så skal jeg igen tjekke kode. Igen kan programmet fint bygges uden at afsløre fejlen.
I Delphi ville qPostnrtabelPostBy-feltet blive omdøbt til qPostnrBy og programmet ville ikke kunne kompilere, uden at alle steder var blevet rettet (hvilket var meget let).
Hvorfor kan man ikke gøre samme i C# ?
En anden ting jeg allerede har set en del er: Hvorfor bruger man ikke parameteriserede scripts? Altid noget med at bygge et script i en streng med parametre og alt: var script = $"select ref, postnr, postby ... where ref={RefNoegle]".
- Sqlserveren vil lave en ny execution plan hver eneste gang scriptet køres? Med parameter-løsningen vil den genbruge og basen vil blive hurtigere.
- En anden og ligeså vigtig ting er faren for SQL-injection!
- Endelig behøver man ikke kere sig om hvorvidt dataformatet skrives "2019-08-28" eller om der er byttet rundt.
Brug dog parametre! Hvorfor gør man sådan i C#?
Der skal noget til at overbevise mig, om at C# er et fremskridt, men prøv. Jeg sidder i suppedasen.