Tidigare har jag sysslat en del med klassiska ASP tillsammans med mySQL. Nu är det dock dags att övergå till ASP.NET med mySQL.
Jag står inför ett hinder, funderar på att bygga en serverkontroll (kompilerad kod till .dll) som sköter arbetet (anslutning, hämtar data, uppdaterar, ta bort data osv..) mot min mySQL databas. Tror det kan kallas DAL?
Min tanke är att en sådan här lösning:
- Skyddar databaslösenordet då det kompileras i en .dll
- Återanvänder samma kod på alla sidor, mindre kod.
- Lättare att ändra till andra databastyper som ex. MS SQL då bara klassen (dll-filen) behöver ändras.
Så jag undrar om det prestandamässigt är bra att använda en sådan här egen kompilerad klass för arbete mot en mySQL-databas?
Hur gör ni vid användning av databaser? Hur inkluderar ni anslutningssträngar till en databas på en aspx-sida?
ASP.NET känns ganska luddigt, men man lär sig något nytt varje dag :)
Jag har tyvärr aldrig sysslat med .NET och dll-filer, så jag kan inte svara bra på din första fråga vad gäller prestandan.
Jag, som inte har applikationer som måste köras med största möjliga säkerhet, kör med en funktion som jag tilldelar en sökväg till en databas när jag ska ansluta till en sådan. Såvitt jag vet går det också att i web.config ange sökväg till en databas, och jag har för mig att det skulle vara säkrare än att skriva ut sökväg m.m. direkt i en codebehind-fil.
Ska bli intressant att läsa om det kommer bra svar här i tråden. Detta är intressant!
Jag har en egen DAL som hanterar de interface som finns mot databaserna. Alltså jag använder exempelvis inte SqlConnection i min DAL utan endast IDbConnection. Om man gör så så är det enkelt att byta ut databas vid ett senare tillfälle.
Angående att kompilera ner lösenordet i en DLL så är det en riktigt dålig ide. När du väl vill ändra detta lösenord så måste du alltså kompilera om din dll och sedan lägga ut den i drift. Sedan har du problemet med att du endast kan ha 1 konto som kopplar sig mot database, och det är inte riktigt vad man vill.
Prestanamässigt så är den tid det tar att skapa sitt DAL och kalla på funktionerna där, jmf med att göra det direkt i sin kod, helt försumbar när man ser hur lång tid det tar att göra databasanropet och hämta data från databasen.
Connectionsträngen läggs fördelaktligen i .config filen så du enkelt kan hämta ut den med hjälp av ConfigSettings i din code.
Själv ville jag att min DAL skulle vara helt självständig så jag skulle slippa skicka med en connectionstring till den, utan den skulle läsa det själv från configfilen, det fungerade inget bra, eftersom den så fall letade efter IIS.exe's config fil. Det fungerade dock ypperligt för WinApps. Det hela slutade med att jag gjorde en egen XML-fil som jag stoppar i samma mapp som min DAL dll och så hämtas connectionsträngen därifrån.
Du skall dock inte göra det som någon ServerControll utan som en vanlig dll. Det är lite skillnad på dessa.
Jag står inför ett hinder, funderar på att bygga en serverkontroll (kompilerad kod till .dll) som sköter arbetet (anslutning, hämtar data, uppdaterar, ta bort data osv..) mot min mySQL databas.
<asp:label runat="server"> är ett exempel på en server control och visst, du kan säkert på något mystiskt sätt skapa en server control som kopplar upp dig mot en databas och hämtar data. :) Vad du är ute efter är en klass som tar emot något, gör något och returnerar något. Klassen kompilerar du till en assembly (dll) och denna använder du sedan för att kommunicera med från andra klasser och funktioner. Objektorientering helt enkelt.
Skyddar databaslösenordet då det kompileras i en .dll
Ja, men nej. En dll kan dekompileras (vet dock inte riktigt hur mycket man får fram). Vad som alltid gäller oavsett sammanhang är att se till att obehöriga överhuvudtaget inte får tag på FILEN som innehåller känslig information.
Återanvänder samma kod på alla sidor, mindre kod.
Yep, det är en mycket bra regel och det är där objektorienteringen kommer in i bilden.
Så jag undrar om det prestandamässigt är bra att använda en sådan här egen kompilerad klass för arbete mot en mySQL-databas?
Kompilerad kod är alltid bra ur prestandasynpunkt. Men sen så gäller såklart att programmeraren ska kunna programmera också... det är vad du gör och hur som sätter prestandan först och främst!
Hur gör ni vid användning av databaser? Hur inkluderar ni anslutningssträngar till en databas på en aspx-sida?
Ja, men nej. En dll kan dekompileras (vet dock inte riktigt hur mycket man får fram). Vad som alltid gäller oavsett sammanhang är att se till att obehöriga överhuvudtaget inte får tag på FILEN som innehåller känslig information! Sen behöver man ju inte skriva lösenord i klartext...
Det känns som om DLL:en är det sista som en eventuell attackerare får tag i. Har denna redan så mycket kontroll över maskinen att han kan ladda ner applikationens binaries, så spelar det ingen roll var någonstans du har ditt lösenord, känns det som. :)
Dessutom har man nog lite andra säkerhetsaspekter att tänka på ifall det händer. ;)
Okej, ur prestandasynvinkel är det ingen förlust att använda sig av en assembly (dll) för att utföra arbete mot databasen. Ett alternativ är alltså att spara lösenordet i web.config för att på ett smidigt sätt kunna inkludera det på sin sajt.
Skulle man inte kunna skapa en sådan dbklass.dll (assembly) med anslutningsträng inbakad till varje webbsajt man har då? Ex. homepage1_dbklass.dll, hompege2_dbklass.dll osv..
Om man har en dbklass.vb fil så går det ju rätt smidigt att kopiera innehållet och skapa en ny med anslutningssträngar.
Om det nu skulle vara så att man vill ansluta till en annan databas än den "standard databas" som är inbakad i klassen, så kanske man skulle kunna "Skriva över" anslutnings-sub:en (kanske kallas ärva?), exempel:
Overrides Public Sub AnslutTillDatabasen()
' En annan anslutningssträng, exempelvis till databas2
End Sub
Sedan kan man fortfarande använda sin homepage1_dbklass.dll till att utföra allt annat? Fast iofs, det kanske inte är så här man löser problem i .NET?
PS. Jag var helt ute och cykla när jag nämnde serverkontroll, som NETwork sa så handlar det om en assembly :)
swordfishy. låt mig säga såhär:
välkommen till VS.NET. Att skapa en databasklass själv är ganska överflödigt eftersom du kan låta VS.NET göra detta åt dig.
Öppna Server Explorer, dra över dom tabeller du vill ha med. Sen trycker du på Generate Dataset på varje adapter som du får upp. Och skickar tabellerna till samma dataset. Så att dataset:et innehåller ALLA tabellerna du tog med.
När du gjort detta så är din databas klass klar, nu har VS.NET skapat alla UPDATE,INSERT,SELECT, DELETE åt dig helt gratis för varje tabell :).
Och som inte detta vore nog ska vi titta lite på hur du skapar relationer mellan tabellerna också: Nu tar du och högerklickar på DataSet11 så du får upp View Schema. Då får du upp en XML fil som innehåller information om relationerna tabellerna emellan i ditt dataSet, så trycker du på New Relation, så får du upp exakt hur du vill att relationen ska länkas, samt om du vill att den ska Cascade:a UPDATE DELETE på andra tabeller om du tar bort/insert i en tabell. Du kan även lägga till nya nycklar om du känner för det etc etc. Och detta har du nu gjort på mindre än 2 min!. Thank you Microsoft!
När du sen ska börja koda så behöver du bara fylla ditt dataSet
Det gör du såhär:
sqlDataAdapter1.Fill(dataSet11);
sqlDataAdapter2.Fill(dataSet11);
osv osv med alla tabellerna.
sen om du vill lägga till en rad i databasen gör du såhär:
Om du tex har en tabell som heter kunder kommer du att få upp detta tabellnamn så fort du använder dataSet:et
dataSet11.kunder.AddkunderRow("pelle","achmedsson");
Lägg också märke till att när du trycker ( i metodanropet så listas alla kolumner i den tabellen. Härligt va? :birp
Och ifall du vill göra en update gör du såhär:
dataSet11.kunder[1].namn="olle";
dataSet11.anvandare[1].efternamn="persson";
Och det ENDA du nu behöver göra för att uppdatera databasen med det du gjort oavsett om det är DELETE,INSERT,UPDATE är detta:
sqlDataAdapter1.Update(dataSet11);
med den adaptern som innehåller tabellen du ändrade i dataSet:et. Och du har inte skrivit 1 rad SQL ;)
Visst är det fint?, detta är så närmast man kan komma object spaces idag. I nästa Visual Studio släpper du en skit så är hela programmet klart i ett naffs :e
Öppna Server Explorer, dra över dom tabeller du vill ha med. Sen trycker du på Generate Dataset på varje adapter som du får upp. Och skickar tabellerna till samma dataset. Så att dataset:et innehåller ALLA tabellerna du tog med.
Gör som Gladh säger : skriv en egen generisk db-klass. Då kan du återanvända den i flera projekt + att det är bra övning!
Connectionstrings placeras som tidigare nämts bäst i web.config Det går utmärkt att kryptera dem om man så önskar :)
Det tillvägagångsätt som nöff beskriver är vad jag vill kalla snabbt, smutsigt och kortsiktigt. Kan fungera på en liten applikation men är helt och hållet uteslutet om man gör en seriös applikation! Det är en mardröm att underhålla en sådan arkitektur och den är inte alls objektorienterad eller återanvändbar.
Jag vet att Gladh la upp ett litet exempel på en dataaccessklass. Sök så hittar du den nog här. Annars finns det bra exempel ute på nätet. Eller fråga specifika frågor här!
Ett annat alternativ är att använda en kodgenerator då dataaccessklasser tenderar att tvinga programmeraren att skriva en massa sql om och om och om igen...
Det ultimata enligt mig om man har en större applikation och måste underhålla den är att använda sig av en o/r mapper.
Det är en mardröm att underhålla en sådan arkitektut
På vilket sätt skulle den vara svår att underhålla?
den är inte alls objektorienterad eller återanvändbar
Vad ska du med återanvändning till när du skapar den på mindre än 2 min?, och vill du lägga till en tabell på ett existing projekt, inga problem, dra bara in den, voila dataSet:et anpassar sig.
Däremot om du har en egenskriven databasklass måste du skriva om SQL satserna ifall du ska applicera den på ett nytt projekt.
:) Nu var det snarare kursens instruktörs tanke, då jag gör mina egna DAL-klasser...men en intressant tankeställare var det iaf :)
Det finns för och nackdelar med allting. Exakt vad är det du ska bygga? Ett Enterprise-system som kommer ta 100-tals, kanske 1000-tals timmar att bygga, samt med 1000-tals samtidiga användare? ...eller är det en mindre sajt med inte så många besökare...?
Bygger du ett stort system, så lägg tid på analays och modellering...även av data-access-lagret...bygg en "super"-DAL-klass, som kan hantera 99% av alla tänkbara funktioner. Men fundera då också exakt VAD det är du har byggt in i ditt DAL som inte redan finns i ADO.NET...OO handlar ju till mycket om återanvändbar kod, och det är ju precis vad du gör när du använder färdiga ADO-klasser.
Jag skulle säga att i de flesta fallen räcker det gott med att bygga en "förenkling" av ADO.NET, ingen ny DAL-klass. Sägg att du på ett enkelt sätt vill kunna anropa en metod med enkla parametrar för att returnera en Reader. Fine, skriv din metod, lägg den i BL. Vad du nu har gjort är att du har förenklat användandet av ADO.NET genom att kunna exekvera SP/SQL-kod med bara ett anrop. Du har däremot inte byggt något DAL, då detta ska kunna fungera helt fristående, oberoende av vilka datakälla som används (I din förenklade metod returnerar du ju fortfarande en SQLDataReader och då är beroden av just SQLClient-NS).
Men som sagt...om du vill ha 110% kontroll och flexibilitet, så lägg tid och tankar på ett riktigt DAL, särskilt i större system, där du har flera projekt som ska använda samma metoder.
Kanske inte helt glasklart, men det är ju bara morgon än... :)
bygg en "super"-DAL-klass, som kan hantera 99% av alla tänkbara funktioner.
Varför 99% när du kan bygga den så att den klara 100% av alla fall.
Nöffs förslag att använda DataSets är ett klart fungerande förslag som lämpar sig väl för mindre och enklare lösningar. Men så fort man kommer upp i större system så blir det jobbigt att syssla med datasets.
Enligt min åsikt (jag vet att alla inte håller med) så skall ett objekt typ, Customer, innehålla både logik och data. Vilket då gör att en O/R Mapper är att föredra framför användadet av DataSets.
Är det så att man delar upp sin logik och data i 2 klasser alltså en CustomerDataClass och en CustomerManagerClass så kan man nästan lika gärna använda sig av DataSets och sin CustomerManagerClass eftersom det enda som CusomerDataClassen så fall innehåller precis det som finns i DataSetet.
Anledningen till att man inte skall använd sig av DataSet överhuvudtaget är att prestandan blir lidande.
På vilket sätt skulle den vara svår att underhålla?
Oj. Du har aldrig utvecklat en större lösning antar jag? Du kommer att behöva upprepa din procedur för varje sida eller funktion du vill ha. har du sedan en medelstor databas med 50 tabeller i får du ett dataset som knappt är hanterbart och i princip omöjligt att serialisera.
Säg att du gör en förändnring i databasen efter ett tag. Då måste du plöja igenom tusentals rader kod och modifiera.
Har du ett generiskt dal så ligger relevant kod samlat i samma lager med logiskt uppdelade namn. Uppdaterat på ganska kort tid om du har tur
Med en o/r mapper ändrar du bara i din dataklass och attribut eller xml-fil. :)
Vad ska du med återanvändning till när du skapar den på mindre än 2 min?, och vill du lägga till en tabell på ett existing projekt, inga problem, dra bara in den, voila dataSet:et anpassar sig.
Återigen: inga större projekt fungerar på det sättet. Men jag håller med om att det självklart är ett bra sätt på en liten lösning.
Kanke kan tyckas löjligt att jag tjatar om större projekt men enligt mina erfarenheter så tenderar folk att göra som de alltid har gjort i sina små hemmaprojekt även i större sammanhang. Dels av okunskap men oftast så tror man helt enkelt inta att projekten ska bli så stora.
Varför 99% när du kan bygga den så att den klara 100% av alla fall.
Ja, jag skule nog vilja säga 99% iaf, möjligen 99,5% :)
...eller har du tex. stöd för ALLT i ditt DAL som är tänkbart? Exempelvis DataMapping (som nu kanske inte är alltför användbart, men som ändå finns...) ?
Jag håller för övrigt med dig om att när du väl har byggt ett bra DAL, så självklart ska du använda det. Det gör även jag.
Inser att jag kanske pajjar trådförfattarens tråd en aning med större designkoncept och objektorienterad metodik.
Tillbaka till pudelns kärna!
Vill du kunna byta databas lätt eller använda olika databaser i samma projekt:
Bygg ett generiskt DAL som inte använder sig av specifika providers itan som Gladh sa Interfacen till dessa.
Ärv sedan denna klass till specifika klasser som hanterar respektive databas.
Lagra din connectionsträng i web.config och kryptera den vid behov.
Välj själv hur du vill returnera data: Datasets, datatables eller egna dataobjekt.
Om det är prestanda du är ute efter (som du nämnde) så använder du egna dataobjek. Men i ett mindre projekt mäker du absolut ingen skillnad.
Är du ute efter att bli en bra .NET programmerare provar du båda sätten :)
Säg att du gör en förändnring i databasen efter ett tag. Då måste du plöja igenom tusentals rader kod och modifiera.
What?. Jag plöjer inte igenom nåt, jag högerklickar på dataadaptern som innehåller den modifierade databastabellen och trycker delete, och drar in den igen. Så... nu är dataSet:et uppdaterat med de nya kolumnerna i databastabellen. Samt så blir dataSet:et type-safe också, är en kolumn DateTime i databasen får kolumnen i dataSet:et samma typ.
Du kommer att behöva upprepa din procedur för varje sida eller funktion du vill ha
Ge dig nu, Upprepa procedur för varje sida?. vad är det du pratar om, klassisk ASP eller? :h
logiskt uppdelade namn
Men du, det är precis det som är ett typat dataSet , dataset:ets tabeller och kolumner namnges efter tabellen och kolumnerna i den riktiga databasen. plus att dom får samma data-typer som databaskolumnerna, Vad mer kan man begära? :bire
OK. Förstår inte riktigt hur du menar då kanske :)
Har du bara en klass med din dataadapter som du generear om? Har du i så fall hela databasen i ditt dataset eller?
Jag tror att ni bör testa adapterns och dataSet:ets möjligheter, det är helt otroligt hur enkelt allt blir med dessa två. följ min beskrivning ovan. Jag lovar, ni säger adjö till SQL och databasklasser fortare än kvickt ;)
Har du i så fall hela databasen i ditt dataset eller?
precis men inte alla rader dock, då hade den blivit för fet, dataSet:et kan man säga är en exakt mall-kopia av databasen plus relationerna. Det är faktiskt nästan likadant som O/R mapper, men ändå inte.
145 ms totalt · 3 externa anrop · v20260731065814-full.55e59744