Avatar billede kennedk Nybegynder
25. september 2007 - 19:34 Der er 30 kommentarer og
3 løsninger

Eksempel på datareader og parametre, i forhold til dataAdapter

Hej
jeg sidder og undre mig over forskellen mellem en datareader og en dataAdapter

Jeg har siddet og rodet med .NET i to uger nu (c#), og hver gang jeg skal have noget ud fra en database bruger jeg en dataadapter.

men her inde på exp er der en masse der siger at datareader er meget bedre, men forstår ikke hvordan det fungere.

og jeg kan forstå på det hele at parametre skulle være skide smart, så man slipper for SQL injections osv.

Håber der er nogen der vil stille et par eksempler op hvor det hele bliver forklaret :)
Avatar billede nielle Nybegynder
25. september 2007 - 19:44 #1
En reader bruger du til at tage fat i hvert enkelte linje i søgresultatet i en loop. På den måde får du mulighed for selv at udføre ekstre kode for hver linje

En adapter tager det hele i et hug, og er mere beregnet som en slags rørledning fra en destination til en anden.
Avatar billede neoman Novice
25. september 2007 - 19:44 #2
Avatar billede kennedk Nybegynder
25. september 2007 - 19:45 #3
lige for tiden bruger jeg denne her kode for at hente noget fra en database.

public DataTable GetData(string strSql)
    {
        DataSet objDS = new DataSet();
        OleDbConnection objConn = new OleDbConnection(_strConnString);
        OleDbDataAdapter objDa = new OleDbDataAdapter(strSql, objConn);
        objConn.Open();
        objDa.Fill(objDS);
        objConn.Close();
        return objDS.Tables[0];
    }

Men jeg forstår desværre ikke lige hvad du mener :/
Avatar billede arne_v Ekspert
25. september 2007 - 19:46 #4
En DataAdapter kan bruges til at fylde et DataSet med. Et DataSet har alle raekker
fra en tabel eller query i memory.

En DataReader er pegepind ned i en tabel eller query og har (logisk set) kun en
enkelt raekke i memory.

Det er aabenlyst at DataReader er bedre end DataAdapter/DataSet, hvis vi snakker
meget store data maengder - man vil ikke have 50 GB data i memory (kan formentlig heller
ikke).

Men et DataSet er nemt at arbejde med, fordi man kan gennemtrawle data forfra, bagfra
og sidelaens.

Hvis man vil have samme funktionalitet med DataReader saa laser man op i en collection
af en egen klasse.

Det er meget udbredt til store "rigtige" IT projekter. Men til smaa simple loesninger
er det meget arbejde sammenlignet med bare at bruge det DataSet som Microsft kan
levere en uden at man skal goere noget.
Avatar billede nielle Nybegynder
25. september 2007 - 19:46 #5
Arnes artikel om parameters:

http://www.eksperten.dk/artikler/831
Avatar billede kalp Novice
25. september 2007 - 19:52 #6
Man skal passe på med, at sige DataSet's er gode til hurtige løsninger.
Hvis man f.eks benytter dem sammen med et DataGrid control så er det hammer buggy!!

og det genere mig voldsomt der ikke er blevet gjort noget ved det - men kan være det er bedre i VS2008.

Hvis man skal have hurtig løsning så skal man benytte SqlDataSource som man binder op imod sine kontroller - den fungerer en del bedre og visuelt får man samme resultatet, som ved brug af et dataset, bagved er det dog anderledes:)
Avatar billede nielle Nybegynder
25. september 2007 - 19:55 #7
Et eksempel på hvordan man bruger en reader. Her udskriver jeg blot alle id'ermne til consollen:

        public void GetData(string strSql)
        {
            DataSet objDS = new DataSet();
            OleDbConnection objConn = new OleDbConnection(_strConnString);
           
            objConn.Open();
           
            OleDbCommand cmd = new OleDbCommand(strSql, objConn);
            OleDbDataReader reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                int id = reader.GetInt32(0);
                Console.WriteLine(id);
            }

            reader.Close();
            objConn.Close();
        }
Avatar billede nielle Nybegynder
25. september 2007 - 19:55 #8
Hvis du nogen siden har kodet klassisk ASP: En reader svarer stort set til et recordset.
Avatar billede kennedk Nybegynder
25. september 2007 - 20:08 #9
Hvordan hvis jeg nu har xx antal poster og de skal listes på en hjemmeside, hvordan skal det så gøres?
Avatar billede nielle Nybegynder
25. september 2007 - 20:25 #10
Det er en adapter da ganske udemærket til. :^)
Avatar billede kalp Novice
25. september 2007 - 20:28 #11
kennedk >>

Åbne din database i "server explorer"
Opret en aspx side.. hiv din tabel fra server explorer over i aspx siden og så er oppe og kører.
Avatar billede kennedk Nybegynder
25. september 2007 - 20:30 #12
Nu sidder jeg og leger lidt med et login system og nyhedssystem lidt blandet sammen, jeg er n[et til login systemet.

Men der bruger jeg den adapter til at udskrive fx alle nyhederne.
jeg  bruger tre filer.
i DataAcess.vb

public DataTable GetData(string strSql, string dbPath)
    {
        DataSet objDS = new DataSet();
        OleDbConnection objConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dbPath);

        OleDbDataAdapter objDa = new OleDbDataAdapter(strSql, objConn);

        objConn.Open();
        objDa.Fill(objDS);
        objConn.Close();

        return objDS.Tables[0];
    }

NyhederFac.vb

public DataTable GetAllNyheder()
        {
            DataAccess objData = new DataAccess();

            return objData.GetData("SELECT * FROM tblNyheder ORDER BY fldId DESC", _strDb);
        }


Default.aspx.vb

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            NyhederFac objNyhed = new NyhederFac();
            Label1.Text = "";
            foreach (DataRow Row in objNyhed.GetAllNyheder().Rows)
            {
                Label1.Text += "<h1>" + Row["fldOverskrift"] + "</h1>";
                Label1.Text += "<h6>" + Row["fldDato"] + "</h6>";
                Label1.Text += Row["fldTekst"];
                Label1.Text += "<br /><a href=\"Nyhed.aspx?id=" + Row["fldId"] + "\">Læs mere</a>";
            }
        }
    }

Hvordan kan det gøres med en reader?
Avatar billede nielle Nybegynder
25. september 2007 - 20:32 #13
Skriver du C# kode i VB-filer?
Avatar billede kennedk Nybegynder
25. september 2007 - 20:35 #14
doh :/ nej min fejl, det er selvfølgelig .cs , det er c#
Avatar billede kalp Novice
25. september 2007 - 20:39 #15
public OleDbDataReader GetAllNyheder()
{
OleDbConnection objConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dbPath);

OleDbCommand objDa = new OleDbCommand("SELECT * FROM tblNyheder ORDER BY fldId DESC", objConn);
return objDa.ExecuteReader()         
        }


protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            NyhederFac objNyhed = new NyhederFac();
OleDbDataReader data = objNyhed.GetAllNyheder();

            Label1.Text = "";
            while(data.Read())
            {
                Label1.Text += "<h1>" + data["fldOverskrift"] + "</h1>";
                Label1.Text += "<h6>" + data["fldDato"] + "</h6>";
                Label1.Text += data["fldTekst"];
                Label1.Text += "<br /><a href=\"Nyhed.aspx?id=" + data["fldId"] + "\">Læs mere</a>";
            }
        }
    }
Avatar billede kalp Novice
25. september 2007 - 20:39 #16
utestet.
Avatar billede kalp Novice
25. september 2007 - 20:44 #17
dbPath mangler.. så den skal du udfylde.

kan se i den anden metode, at den hedder "_strDb" men ikke erklæret i selve metoden så hvis den er global kan du bare omdøbe dbPath til _strDb
Avatar billede kennedk Nybegynder
25. september 2007 - 20:49 #18
Nu har jeg default.aspx.cs:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            NyhederFac objNyhed = new NyhederFac();
            OleDbDataReader data = objNyhed.GetAllNyheder();

            Label1.Text = "";
            while (data.Read())
            {
                Label1.Text += "<h1>" + data["fldOverskrift"] + "</h1>";
                Label1.Text += "<h6>" + data["fldDato"] + "</h6>";
                Label1.Text += data["fldTekst"];
                Label1.Text += "<br /><a href=\"Nyhed.aspx?id=" + data["fldId"] + "\">Læs mere</a>";
            }

        }
    }

og NyhederFac.cs

public OleDbDataReader GetAllNyheder()
        {
            OleDbConnection objConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + _strDb);

            OleDbCommand objDa = new OleDbCommand("SELECT * FROM tblNyheder ORDER BY fldId DESC", objConn);
            return objDa.ExecuteReader();
        }

men den skriver: ExecuteReader kræver en åben og tilgængelig forbindelse. Forbindelsens aktuelle tilstand er lukket.
Avatar billede nielle Nybegynder
25. september 2007 - 20:54 #19
Du kalder jo heller ikke en Open() på din connection i GetAllNyheder().
Avatar billede kennedk Nybegynder
25. september 2007 - 20:54 #20
public OleDbDataReader GetAllNyheder()
        {
            OleDbConnection objConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + _strDb);

            OleDbCommand objDa = new OleDbCommand("SELECT * FROM tblNyheder ORDER BY fldId DESC", objConn);
            objConn.Open();
            return objDa.ExecuteReader();
            objConn.Close();
        }

Det virker, men den kan ikke udføre Close(), og det er jo fordi den har returneret noget. Hvad gør man så?
Avatar billede nielle Nybegynder
25. september 2007 - 20:58 #21
Du skal kalde Close() der hvor din GetAllNyheder() aflevere readeren.
Avatar billede kennedk Nybegynder
25. september 2007 - 21:02 #22
Ja, det kan jeg godt se.
men det burde da kunne laves noget helt vild smart.
Hvordan ville i hardcore kodere gøre?
Avatar billede arne_v Ekspert
25. september 2007 - 21:03 #23
.ExecuteReader(CommandBehavior.CloseConnection)
Avatar billede kalp Novice
25. september 2007 - 21:18 #24
Hvis forbindelsen ikke skal benyttes mere så lukker man den som arne_v har vist..

ellers placeres forbindelsen f.eks globalt og der laves en metode til at lukke den når den ikke skal benyttes længere.
Avatar billede kennedk Nybegynder
25. september 2007 - 21:27 #25
så lige en sidste ting :)
Hvordan vil man tjekke med en datareader hvor mange rækker der er i ens forespørgsel?
Avatar billede kalp Novice
25. september 2007 - 21:35 #26
Den har ikke en metode til det.. den kender kun en række af gangen:)
Du kan lave en SQL og udlæse den fra din datareader - eller binde den til et datagrid eller hvad du nu har behov for og i den kalde Items.Count.
Avatar billede arne_v Ekspert
25. september 2007 - 21:35 #27
Afhaenger lidt af konteksten.

Ofte vil man laese ind i en collection som udvides dynamisk og saa har man ikke
brug for at kende antal raekker.

Man kan ogsaa lave en SELECT COUNT(*).
Avatar billede kennedk Nybegynder
25. september 2007 - 21:48 #28
Jeg takker mange gange :) så skal der deles point ud!
Avatar billede kalp Novice
25. september 2007 - 22:10 #29
kennedk >> du bør sige hvem der skal lægge svar.

Jeg lægger et - ikke dermed sagt jeg forventer point:) men så er det gjort.
Avatar billede kalp Novice
25. september 2007 - 22:10 #30
flot.
Avatar billede nielle Nybegynder
26. september 2007 - 08:17 #31
Svar :^)
Avatar billede arne_v Ekspert
27. september 2007 - 03:30 #32
ditto
Avatar billede arne_v Ekspert
27. september 2007 - 04:00 #33
neoman>

Jeg håber du er vældigt tilfreds med den effekt dine reminders har - f.eks. i http://www.eksperten.dk/spm/796063 ...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester