Databashantering i asp.NET
Förord
Detta exempel visar hur man lägger in information i en databas som man hämtat från ett formulär på en ASP.NET sida. Att lägga in information i en databas är något som ni kommer att använda väldigt ofta i projektet och det är därför viktigt att förstå de steg som krävs för att det skall fungera. Principerna som används är de samma som används när man vill göra en select, delete eller update på en databas, vilket innebär att med enbart små modifieringar, som kommer att visas, kan koden åter användas för att genomföra dessa uppgifter. Följande exempel är ett väldigt förenklad återskapelse av en händelse som ni troligen kommer att använda er av i projektet; att lägga till en nu kund i databasen.Innehåll
»»
»
OBS artikeln är i sin fulla längd men formateringen är fel och vi hoppas Pelle åtgärdar detta inom snar framtid.
När detta är klar kommer du att ha skapat en sida som ser ut som följande:
Om man tittar på den nyskapade sidan i kod läge, genom att ställa om från design till html i WebMatrix ser man att följande html-kod har skapats:
Nu när själva design biten av exemplet är klar, är det dags att börja med den programmering som kommer att genomföra insert anropet mot databasen.
Den kod som behövs för att hantera att användaren trycker på knappen Lägg till är nu skapad. Vad som återstår att göra, är att skriva den kod som utföra vår insert. Denna kod skall placeras i händelsehanteraren för Button1, som vi precis skapade:
Den fullständiga koden för att genomföra ett insert anrop (samt delete och update anrop) ser ut enligt följande:
Som det nämndes tidigare, så skiljer sig ett select anrop mot en databas då det returnerar information från databasen till sidan som anropade den. Med anledning av detta måste man ta hänsyn till att lagra retur informationen så man kan använda den så som man önskar.
Principerna för att genomföra en select är desamma som tidigare kod fast med ett par små modifieringar.
Den fullständiga koden för att genomföra ett anrop av typen select mot en databas, och lagra retur informationen i ett DataSet är följande:
Denna information kan sedan användas för att visa i en tabell, lista eller t.ex. för att användas som parametrar för andra anrop mot en databas.
I den kod som har använts för att göra ett anrop mot en databas, användes SqlParameter för att ersätta platshållarna med de riktiga värden som vi vill skicka med. Med klassen har vi skickat med tre olika parametrar, som kan behöva lite förklaring för att den koden skall kunna användas vid andra fall.
Parametrarna är numrerade efter den ordning de förekommer:
Insert, delete och update
- Starta WebMatrix och skapa ett nytt projekt av typen ASP.NET Page.
- Ge filen namnet Insert.aspx.
- Kontroller att det valda språket för sidan är C#.
- Klicka sedan på OK för att skapa sidan.
- Kontrollera att sidan visas i design läge.
- Lägg till Label, från toolbox fönstret, på sidan och ställ om dess Text egenskap i Properties fönstret till Förnamn.
- Lägg till en TextBox, från toolbox fönster, på sidan.
- Placera markören efter fältet och infoga ny rad (tryck return).
- Lägg till Label, från toolbox, fönstret på sidan och ställ om dess Text egenskap i Properties fönstret till Efternamn.
- Lägg till en TextBox, från toolbox fönster, på sidan.
- Placera markören efter fältet och infoga ny rad (tryck return).
- Lägg till en Button, från toolbox fönstret, på sidan och ställ om dess Text egenskap i Properties fönstret till Lägg till.
- Placera markören efter knappen och infoga ny rad (tryck return).
- Lägg till Label, från toolbox, fönstret på sidan och ställ om dess Text egenskap i Properties fönstret till ett tomt värde.
När detta är klar kommer du att ha skapat en sida som ser ut som följande:
Om man tittar på den nyskapade sidan i kod läge, genom att ställa om från design till html i WebMatrix ser man att följande html-kod har skapats:
Nu när själva design biten av exemplet är klar, är det dags att börja med den programmering som kommer att genomföra insert anropet mot databasen.
- Byta visningsläge från design till all.
- Infoga nedanstående kod längst upp på sidan, under <%@ Page Language=”C#” %>. Denna kod informerar ASP.NET var den kan hitta de SQL klasser som vi senare kommer att använda för att göra anrop mot databasen.
- Växla tillbaka visningsläget till design från all.
- Markera objektet Button1 i properties fönstret
- Visa objektets händelselista genom att trycka på knappen Events.
- Dubbelklicka i rutan för Click händelsen, för att låta WebMatrix skapa den kod som behövs för att hantera händelsen.
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.SqlClient" %>
Den kod som behövs för att hantera att användaren trycker på knappen Lägg till är nu skapad. Vad som återstår att göra, är att skriva den kod som utföra vår insert. Denna kod skall placeras i händelsehanteraren för Button1, som vi precis skapade:
void Button1_Click(object sender, EventArgs e)
{
}
- Det första som skall göras är att skapa en textvariable som innehåller det SQL anrop vi vill genomföra. Observera att i nedanstående kod använder vi oss av två, så kallade, platshållare; @firstname och @lastname i SQL anropet. Dessa två kommer lite senare att ersättas med de faktiska värdena, och kommer aldrig att skickas till databasen.
Om vi istället skulle göra ett delete eller update anrop mot databasen, skulle vi här fylla i respektive SQL-sats. Även i dessa fall är det lämpligt att använda sig av platshållare för de värden som skall skickas med. Anrop av typen select fungerar lite annorlunda då, tillskillnad mig insert, delete och update så returnerar ett select anrop värde från databasen till sidan, och därför behandlas dessa separat. - Nästa sak som måste genomföras, är att skapa en koppling mot SQL servern och den database som vi skall använda. Parametrarna user id, password och database, fyller ni i ert gruppnamn och lösenord (tänk på att namnet för er databas är detsamma som ert gruppnamn).
- Nu är det dags att skapa det SQL anrop (även kallat kommando) som vi vill använda mot databasen. Detta kommando tar vår SQL-sats, samt en referens till vilken SQL koppling den skall arbeta mot.
- När allt detta är klart, skall vi ersätta platshållarna @firstname och @lastname, med de riktiga värdena som vi hämtar från de fält vi placerat på sidan. Mer information om klassen SqlParameter finner ni i slutet på detta exempel.
- Den sista biten kod att implementera, är den som gör det faktiskt arbetat för vårt SQL anrop. Innan vi kan göra anropet måste vi öppna kopplingen mot databasen, samt, kontrollera att den gick att öppna innan vi försöker använda den.
Om man inte kontrollerar att man har en öppen koppling mot databasen innan man anropar den, riskerar man att få en massa felmeddelande som kommer att presenteras för användaren av sidan.
När det är bekräftat att det finns en öppen koppling mot databasen, genomför vi vårt anrop och sedan stänger vi kopplingen igen. Det är väldigt viktigt att man inte glömmer att stänga en öppnad koppling i ASP.NET eftersom det lämnar öppna resurser som använder sig av resurser så som minne, samt kan försämra prestandan vid upprepade anrop.
myCommand.Connection.Open();
if( myCommand.Connection.State == ConnectionState.Open )
{
myCommand.ExecuteNonQuery();
myCommand.Connection.Close();
Label3.Text = "Uppgifterna har nu lagrats i databasen.";
}
else
{
Label3.Text = "Det gick inte att öppna databasen.”;
}
}
Koden skriver även ut om anropet misslyckades eller inte (i vårt fall skriver den ut att det inte lyckades, om en koppling mot databasen inte gick att genomföra).
string mySQL = "insert into kunder (firstname, lastname) values (@firstname, @lastname)";
SqlConnection myConnection =
new SqlConnection("server=sql001.hbg.lu.se; user id=''; password='' database=''");
SqlCommand myCommand = new SqlCommand(mySQL, myConnection);
myCommand.Parameters.Add( new SqlParameter("@firstname", SqlDbType.VarChar, 15));
myCommand.Parameters["@firstname"].Value = TextBox1.Text;
myCommand.Parameters.Add( new SqlParameter("@lastname", SqlDbType.VarChar, 15));
myCommand.Parameters["@lastname"].Value = TextBox2.Text;
Den fullständiga koden för att genomföra ett insert anrop (samt delete och update anrop) ser ut enligt följande:
void Button1_Click(object sender, EventArgs e)
{
string mySQL = "insert into kunder (firstname, lastname) values (@firstname, @lastname)";
SqlConnection myConnection =
new SqlConnection("server=sql001.hbg.lu.se; user id=''; password='' database=''");
SqlCommand myCommand = new SqlCommand(mySQL, myConnection);
myCommand.Parameters.Add( new SqlParameter("@firstname", SqlDbType.VarChar, 15));
myCommand.Parameters["@firstname"].Value = TextBox1.Text;
myCommand.Parameters.Add( new SqlParameter("@lastname", SqlDbType.VarChar, 15));
myCommand.Parameters["@lastname"].Value = TextBox2.Text;
myCommand.Connection.Open();
if( myCommand.Connection.State == ConnectionState.Open )
{
myCommand.ExecuteNonQuery();
myCommand.Connection.Close();
Label3.Text = "Uppgifterna har nu lagrats i databasen.";
}
else
{
Label3.Text = "Det gick inte att öppna databasen.”;
}
}
Select
Som det nämndes tidigare, så skiljer sig ett select anrop mot en databas då det returnerar information från databasen till sidan som anropade den. Med anledning av detta måste man ta hänsyn till att lagra retur informationen så man kan använda den så som man önskar.Principerna för att genomföra en select är desamma som tidigare kod fast med ett par små modifieringar.
- Föreställ er att vi skall hämta ut alla kunder som bor i helsingborg. För detta skapar vi oss följande SQL-sats
- Istället för att använda ett SqlCommand så använder man sig av en klass som heter SqlDataAdapter. Denna klass har till uppgift att ta retur informationen från ett anrop och lagra det för senare användning.
- SqlDataAdapter använder sig oxå av en samling SqlParameter objekt för att ersätta platshållare med riktiga värden. Dock finns det en liten skillnad och det är hur man kommer åt att lägga in nya SqlParameter objekt.
- Innan vi kan genomföra vårt anrop till databasen, måste vi skapa en variable som kan lagra retur informationen i. För detta använder man sig av en klass som heter DataSet, som är en klass anpassad för att kunna lagra retur informationen, intakt med kolumn information, eventuella relationer, primärnycklar etc.
- Anropet genomsförs sedan genom att man använder sig av metoden fill() på klassen SqlDataAdapter som genomför anropet och lagrar resultaten i det DataSet som man skickar med, i en lokal tabell med valfritt namn, i vårt fall i tabellen kunder.
string mySQL = ”select * from kunder where kunder.ort = @city”
SqlDataAdapter myAdapter = new SqlDataAdapter(mySQL, myConnection);
myAdapter.SelectCommand.Parameters.Add(new SqlParameter("@city", SqlDbType.VarChar, 15));
myAdapter.SelectCommand.Parameters["@city"].Value = TexBox1.Text;
DataSet myDataSet = new DataSet();
myAdapter.Fill(myDataSet, "Kunder");
Den fullständiga koden för att genomföra ett anrop av typen select mot en databas, och lagra retur informationen i ett DataSet är följande:
string mySQL = ”select * from kunder where kunder.ort = @city”
SqlDataAdapter myAdapter = new SqlDataAdapter(mySQL, myConnection);
myAdapter.SelectCommand.Parameters.Add(new SqlParameter("@city", SqlDbType.VarChar, 15));
myAdapter.SelectCommand.Parameters["@city"].Value = TexBox1.Text;
DataSet myDataSet = new DataSet();
myAdapter.Fill(myDataSet, "Kunder");
Denna information kan sedan användas för att visa i en tabell, lista eller t.ex. för att användas som parametrar för andra anrop mot en databas.
Mer om SqlParameter
I den kod som har använts för att göra ett anrop mot en databas, användes SqlParameter för att ersätta platshållarna med de riktiga värden som vi vill skicka med. Med klassen har vi skickat med tre olika parametrar, som kan behöva lite förklaring för att den koden skall kunna användas vid andra fall.Parametrarna är numrerade efter den ordning de förekommer:
- Detta är namnet på den platshållare, som man vill att det riktiga värdet skall ta plats för.
- Med hjälp av denna parametern berättar man vad det är för datatyp som parametern motsvarar. Denna skall vara det samma som den datatyp motsvarande kolumn i tabellen i fråga är inställd på i SQL-Server.
Följande värde är giltiga:BigInt, Binary, Bit, Char, DateTime, Decimal, Float, Image, Int, Money, NChat, NText, NVarChar, Real, SmallDateTime, SmallInt, SmallMoney, Text, TimeStamp, TinyInt, UniqueIdentifier, VarBinary, VarChar och Variant. - Den sista parametern anger längden (i bytes) på den datatyp för den angivna datatypen och skall vara samma längd som är valt för kolumnen i fråga i SQL-Server.
Martin Berlin
Förstår inte riktigt varför du använder dig av "vilda SQL-satser" istället för stored procedures ?
Andreas Håkansson
Anledningen är tvåfaldig - för det första skrevs detta som lektionsmaterial till en högskolekurs i Databashantering och eleverna laborerade innan de hade gått igenom stored procedures (det blev en seperat lektion för det, med egen kod) och den andra anledningen är för att hålla exemplet enkelt och inte blanda in kluriga saker för nybörjare.