Avatar billede Slettet bruger
24. marts 2006 - 14:23 Der er 32 kommentarer og
1 løsning

Data access layer (VB.NET)

Hej

Jeg er (stadig) ny i den her kode-verden.

Det er efterhånden gået op for mig at det er smart at dele sine websider op i 3 lag (præsentation, business og data access). Men jeg kan ikke få overblik over hvordan det gøres.

Jeg bruger VB.NET/ASP.NET og Microsoft Access db og visual studio 2005 (Beta).

Findes der et sted eller en som på en grundig og simpel måde kan forklare mig hvordan det laves i praksis?
Avatar billede arne_v Ekspert
24. marts 2006 - 14:36 #1
nu findes der faktisk forskellige maader at dele sin kode op paa, men de
3 lag er den klassiske

2005 er paa gaden i endelig udgave !

det er faktisk ikke helt simpelt at lave en god struktur paa sin kode

websam har stillet en del spoergsmaal i samme anledning, bl.a.:

http://www.eksperten.dk/spm/654026
http://www.eksperten.dk/spm/690642
http://www.eksperten.dk/spm/692443
http://www.eksperten.dk/spm/695119

maaske kunne du starte med at laese dig igennem disse traade
Avatar billede Slettet bruger
24. marts 2006 - 14:48 #2
Det starter jeg med. Tak.
Avatar billede Slettet bruger
29. marts 2006 - 12:57 #3
Hej

Det er vist en lang vej for mig at forstå. Men jeg kigger stille og roligt på det - håber du har lidt tålmodighed.

Mit første skridt at at bruge codebehind, og jeg har i den forbindelse prøvet at lave en dropdownlist. Det er så meningen at jeg vil udvide det til at trække data via DAL til DDL, men en ting ad gangen :-)

Mit problem er at jeg ikke engang kan få den til at hente data fra codebehind-filen. Her er min to filer:

<%@ Page Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false" CodeFile="Afvigelser_index.aspx.vb" Inherits="Afvigelser_index" title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="AreamenuHolder" Runat="Server">
    Areamenu</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContentHolder" Runat="Server">

Ansvarlig for opfølgning:
    <asp:DropDownList ID="test" runat="server" />
    </asp:Content>

Og codebehind:

<%@ Page Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false" CodeFile="Afvigelser_index.aspx.vb" Inherits="Afvigelser_index" title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="AreamenuHolder" Runat="Server">
    Areamenu</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContentHolder" Runat="Server">

Ansvarlig for opfølgning:
    <asp:DropDownList ID="test" runat="server" />
    </asp:Content>

Kan ud hjælpe mig med det?
Avatar billede Slettet bruger
29. marts 2006 - 22:47 #4
Hej igen

Jeg oprette et spørgsmål seperat til ovenstående spørgmål
Avatar billede Slettet bruger
03. april 2006 - 11:55 #5
Jeg har læst og læst og prøvet og prøvet, men det er svært syntes jeg. Jeg har vist brug for et eksempel - må jeg henvise til http://www.eksperten.dk/spm/700204?
Avatar billede Slettet bruger
08. april 2006 - 13:36 #6
Laver man en klasse til hvert DTO?
Hvis man f.eks. har to dropdownlister (f.eks. ”afdelinger” og ”medarbejdere” ), som går igen på forskellige sider, nogen gange sammen og nogen gange hver for sig, laver man så et DTO for afdelinger og et for medarbejdere eller laver et til hver og et til begge?

Kunne dette være en fremgangsmåde til at definere et DTO ser det sådan her ud (f.eks.)?

ClassDTOAfdelinger

Private _afdelingsnavn as string = ””
Private _afdelingsnummer as integer  = ””

Kalder databasen og henter afdelingsnavn og afdelingsnummer
Returnere en datareader eller dataset

Public Property afdelingsnavn() As String
Her sætter man property afdeligsnavn = datareaderen(afdelingsnavn)
End property

End ClassDTOAfdelinger

Når man så skal bruge/binde afdelingerne til en dropdownlist gør man så følgende?

Sub Page_Load()
Dim Afdelingsnavn As String
Afdelinger = ClassDTOAfdelinger.afdelingsnavn
Binder afdelinger til dropdownlisten
End sub

Hvis denne fremgangsmåde er nogen lunde acceptabel, vil jeg meget gerne hvis jeg kunne få vist fremgangsmåde til at sætte property afdeligsnavn()?

På forhånd tak.
Avatar billede arne_v Ekspert
08. april 2006 - 15:30 #7
du skal have en DTO for hver type af objekt (en for medarbejder og en for afdeling)

DTO har kun fields, properties, constructor, tostring, compare og dem slags

database koden skal ligge i en anden klasse
Avatar billede Slettet bruger
09. april 2006 - 16:03 #8
Tak.

Kan jeg få dig til at lave et eksempel på hvordan man sætter DTO-properties og hvordan man kalder DTO-properties?
Avatar billede arne_v Ekspert
09. april 2006 - 16:40 #9
DTO properties er helt normale VB.NET properties
Avatar billede arne_v Ekspert
09. april 2006 - 16:42 #10
banale eksempler:

Imports System

Namespace E
    Public Class A
        Private _s As String
        Public Sub New()
            MyClass.New("")
        End Sub
        Public Sub New(ByVal s As String)
            _s = s
        End Sub
        Public Property S() As String
            Get
                Return _s
            End Get
            Set
                _s = value
            End Set
        End Property
        Public Overloads Overrides Function ToString() As String
            Return s
        End Function
    End Class
    Public Class B
        Private Const DEF_S As String = ""
        Private _s As String
        Public Sub New()
            MyClass.New(DEF_S)
        End Sub
        Public Sub New(ByVal s As String)
            _s = s
        End Sub
        Public Property S() As String
            Get
                Return _s
            End Get
            Set
                _s = value
            End Set
        End Property
        Public Overloads Overrides Function ToString() As String
            Return s
        End Function
    End Class
End Namespace
Avatar billede Slettet bruger
10. april 2006 - 09:50 #11
Kan en property godt være et sæt af data. F.eks. i nedenstående eksempel, hvor jeg har forsøgt mig lidt frem, er res flere afdelinger (id, afdelingsnr og afdelingsnavn).

Jeg er desuden løbet ind i følgende problem:
Den siger at id, afdelingsnr, afdelingsnavn i linien "res = New RSDAfdelinger(id, Afdelingsnr, Afdelingsnavn)" i "Class RSDAfdelingerDB" ikke er declaret. Jeg syntes ikke det fremgår at det jeg læser at jeg skal "dim" dem, laver jeg en anden fejl?

Imports System
Imports System.Data
Imports System.Data.OleDb

Namespace DAL

    Public Class DataHelperClass

        Private Function ConnectingString() As String
            Return "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA Source=c:\inetpub\wwwroot\database\database.mdb"
        End Function

        Public Function GetConnection() As OleDbConnection
            Dim Connection As New OleDbConnection(ConnectingString())
            Connection.Open()
            GetConnection = Connection
        End Function

    End Class

    Public Class RSDAfdelinger
        Private _id As Integer
        Private _Afdelingsnr As String
        Private _Afdelingsnavn As String

        Public Sub New()
            MyClass.New(0, "", "")
        End Sub

        Public Sub New(ByVal id As Integer, ByVal Afdelingsnr As String, ByVal Afdelingsnavn As String)
            _id = id
            _Afdelingsnr = Afdelingsnr
            _Afdelingsnavn = Afdelingsnavn
        End Sub

        Private Property id() As Integer
            Get
                Return _id
            End Get
            Set(ByVal value As Integer)
                _id = value
            End Set
        End Property

        Public Property Afdelingsnr() As String
            Get
                Return _Afdelingsnr
            End Get
            Set(ByVal value As String)
                _Afdelingsnr = value
            End Set
        End Property

        Public Property Afdelingsnan() As String
            Get
                Return _Afdelingsnavn
            End Get
            Set(ByVal value As String)
                _Afdelingsnavn = value
            End Set
        End Property

    End Class

    Friend Class RSDAfdelingerDB
        Public Shared Function GetRSDAfdelinger()
            Dim res As RSDAfdelinger

            Dim DbConn As DataHelperClass = New DataHelperClass
            Dim Conn As OleDbConnection = DbConn.GetConnection()
            Dim Reader As OleDbDataReader
            Dim SqlCmd As New OleDbCommand("SELECT id, afdelingsnr, afdelingsnavn FROM Afdelinger", Conn)
            Reader = SqlCmd.ExecuteReader()
            If Reader.Read Then
                res = New RSDAfdelinger(id, Afdelingsnr, Afdelingsnavn)
            Else
                res = Nothing
            End If
            Conn.Close()
            Conn = Nothing
            Return res
        End Function

    End Class
End Namespace
Avatar billede Slettet bruger
10. april 2006 - 14:09 #12
Æv - er I taget på påskeferie?
Avatar billede arne_v Ekspert
10. april 2006 - 14:36 #13
det er helt normlat at en DTO klasse har flere properties (dett vil nok naermest
aldrig ses at der kun er en som i mit banale eksempel)\
Avatar billede Slettet bruger
10. april 2006 - 14:46 #14
Hej

Men det jeg mener er om der f.eks. til propertien _afdelingsnr kan være knyttet et sæt af afdelinger?

Og så var der:

Jeg er desuden løbet ind i følgende problem:
Den siger at id, afdelingsnr, afdelingsnavn i linien "res = New RSDAfdelinger(id, Afdelingsnr, Afdelingsnavn)" i "Class RSDAfdelingerDB" ikke er declaret. Jeg syntes ikke det fremgår at det jeg læser at jeg skal "dim" dem, laver jeg en anden fejl?

Som jeg ikke helt forstår
Avatar billede arne_v Ekspert
10. april 2006 - 14:49 #15
en afdelings klasse vil kun indeholde et afdelingsnr

en firma klasse kan indeholde en collection af afdelings klasser

jeg tror at din RSDAfdelingerDB / GetRSDAfdelinger skal restruktureres lidt
Avatar billede Slettet bruger
10. april 2006 - 15:13 #16
Kan du se hvordan jeg skal restrukturere det?
Avatar billede arne_v Ekspert
10. april 2006 - 15:37 #17
grundliggende skal du vel have 2 metoder:

- en uden argumenter som returnerer en collection af RSDAfdelinger objekter
- en med argument afdelingsnr som returnerer en enkelt RSDAfdelinger
Avatar billede Slettet bruger
12. april 2006 - 11:00 #18
Hej

Jeg starter lige med at prøve at hente én afdeling. Det jeg ikke kan få til at virke er implements i Public Class RSDAfdelingerDB. Den giver følgende fejl, som jeg ikke forstår:


Error    2    Class 'RSDAfdelingerDB' must implement 'Function GetRSDAfdeling() As RSDAfdeling' for interface 'IRSDAfdeling'.

Er jeg, ud over den fejl, ved at have lavet noget, der ser fornuftigt ud?

Min kode:

Imports Microsoft.VisualBasic
Imports System
Imports System.Data
Imports System.Data.OleDb
Imports System.Collections

Namespace DAL

    Public Class DataHelperClass

        Private Function ConnectingString() As String
            Return "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA Source=c:\inetpub\wwwroot\database\database.mdb"
        End Function

        Public Function GetConnection() As OleDbConnection
            Dim Connection As New OleDbConnection(ConnectingString())
            Connection.Open()
            GetConnection = Connection
        End Function

    End Class


    Public Class RSDAfdeling
        Private _id As Integer
        Private _Afdelingsnr As String
        Private _Afdelingsnavn As String

        Public Sub New()
            MyClass.New(0, "", "")
        End Sub

        Public Sub New(ByVal id As Integer, ByVal Afdelingsnr As String, ByVal Afdelingsnavn As String)
            _id = id
            _Afdelingsnr = Afdelingsnr
            _Afdelingsnavn = Afdelingsnavn
        End Sub

        Public Property id() As Integer
            Get
                Return _id
            End Get
            Set(ByVal value As Integer)
                _id = value
            End Set
        End Property

        Public Property Afdelingsnr() As String
            Get
                Return _Afdelingsnr
            End Get
            Set(ByVal value As String)
                _Afdelingsnr = value
            End Set
        End Property

        Public Property Afdelingsnavn() As String
            Get
                Return _Afdelingsnavn
            End Get
            Set(ByVal value As String)
                _Afdelingsnavn = value
            End Set
        End Property

    End Class


    Public Interface IRSDAfdeling
        Function GetRSDAfdeling() As RSDAfdeling
    End Interface


    Public Class RSDAfdelingerDB
        Implements IRSDAfdeling

        Public Function GetRSDAfdeling() As RSDAfdeling
            Dim DBConn As DataHelperClass = New DataHelperClass
            Dim Conn As OleDbConnection = DBConn.GetConnection()
            Dim SqlCmd As New OleDbCommand("SELECT id, afdelingsnr, afdelingnavn FROM Afdelinger WHERE id = 10", Conn)
            Dim Reader As OleDbDataReader = SqlCmd.ExecuteReader
            Dim res As RSDAfdeling = New RSDAfdeling

            While Reader.Read
                res.id = Convert.ToInt32(Reader("id"))
                res.Afdelingsnr = Convert.ToString(Reader("afdelingsnr"))
                res.Afdelingsnavn = Convert.ToString(Reader("afdelingsnavn"))
            End While

            Reader.Close()
            Reader = Nothing
            Conn.Close()
            Conn = Nothing
            Return res
        End Function

    End Class
End Namespace
Avatar billede Slettet bruger
12. april 2006 - 13:33 #19
Hej

...andre må naturligvis også gerne byde ind. Jeg sidder lidt og hiver mig i håret og kan ikke rigtig regne ud hvad der skal til for at løse problmet.
Avatar billede arne_v Ekspert
12. april 2006 - 13:44 #20
Public Function GetRSDAfdeling() As RSDAfdeling Implements IRSDAfdeling GetRSDAfdeling()
Avatar billede Slettet bruger
19. april 2006 - 08:41 #21
Tak.

Nu er jeg lige ved at være der. Hvis det er ok (sig til hvis jeg skal lave et nyt spm), vil jeg gerne bede om hjælp til at komme det sidste stykke, og jeg vil meget gerne høre om de kritiske ting, der er i den måde, det er lavet på indtil nu.

Mit problem er at der ikke kommer noget i min dropdownlist.

DAL:

Imports Microsoft.VisualBasic
Imports System
Imports System.Data
Imports System.Data.OleDb
Imports System.Collections

Namespace DAL

    Public Class DataHelperClass

        Private Function ConnectingString() As String
            Return "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA Source=c:\inetpub\wwwroot\database\database.mdb"
        End Function

        Public Function GetConnection() As OleDbConnection
            Dim Connection As New OleDbConnection(ConnectingString())
            Connection.Open()
            GetConnection = Connection
        End Function

    End Class


    Public Class RSDAfdeling
        Private _id As Integer
        Private _Afdelingsnr As String
        Private _Afdelingsnavn As String

        Public Property id() As Integer
            Get
                Return _id
            End Get
            Set(ByVal value As Integer)
                _id = value
            End Set
        End Property

        Public Property Afdelingsnr() As String
            Get
                Return _Afdelingsnr
            End Get
            Set(ByVal value As String)
                _Afdelingsnr = value
            End Set
        End Property

        Public Property Afdelingsnavn() As String
            Get
                Return _Afdelingsnavn
            End Get
            Set(ByVal value As String)
                _Afdelingsnavn = value
            End Set
        End Property

        Public Sub New()
            Call MyClass.New(0, "", "")
        End Sub

        Public Sub New(ByVal id As Integer, ByVal Afdelingsnr As String, ByVal Afdelingsnavn As String)
            _id = id
            _Afdelingsnr = Afdelingsnr
            _Afdelingsnavn = Afdelingsnavn
        End Sub

    End Class


    Public Interface IRSDAfdelingDB
        Function GetRSDAfdeling() As RSDAfdeling
        Function GetAllRSDAfdeling() As ArrayList
    End Interface


    Public Class RSDAfdelingerDB
        Implements IRSDAfdelingDB

        Public Function GetRSDAfdeling() As RSDAfdeling Implements IRSDAfdelingDB.GetRSDAfdeling
            Dim DBConn As DataHelperClass = New DataHelperClass
            Dim Conn As OleDbConnection = DBConn.GetConnection()
            Dim SqlCmd As New OleDbCommand("SELECT id, afdelingsnr, afdelingsnavn FROM Afdelinger WHERE id = 12", Conn)
            Dim Reader As OleDbDataReader = SqlCmd.ExecuteReader
            Dim objRSDAFdeling As RSDAfdeling = New RSDAfdeling

            While Reader.Read
                objRSDAFdeling.id = Convert.ToInt32(Reader("id"))
                objRSDAFdeling.Afdelingsnr = Convert.ToString(Reader("afdelingsnr"))
                objRSDAFdeling.Afdelingsnavn = Convert.ToString(Reader("afdelingsnavn"))
            End While

            Reader.Close()
            Reader = Nothing
            Conn.Close()
            Conn = Nothing
            Return objRSDAFdeling
        End Function


        Public Function GetAllRSDAfdeling() As ArrayList Implements IRSDAfdelingDB.GetAllRSDAfdeling
            Dim DBConn As DataHelperClass = New DataHelperClass
            Dim Conn As OleDbConnection = DBConn.GetConnection()
            Dim SqlCmd As New OleDbCommand("SELECT id, afdelingsnr, afdelingsnavn FROM Afdelinger", Conn)
            Dim Reader As OleDbDataReader = SqlCmd.ExecuteReader
            Dim objListRSDAfdeling As ArrayList

            While Reader.Read
                Dim objRSDAFdeling = New RSDAfdeling
                objRSDAFdeling.id = Convert.ToInt32(Reader("id"))
                objRSDAFdeling.Afdelingsnr = Convert.ToString(Reader("afdelingsnr"))
                objRSDAFdeling.Afdelingsnavn = Convert.ToString(Reader("afdelingsnavn"))
                objListRSDAfdeling.Add(objRSDAFdeling)
            End While

            Reader.Close()
            Reader = Nothing
            Conn.Close()
            Conn = Nothing
            Return objListRSDAfdeling
        End Function

    End Class
End Namespace


BLL:

Imports Microsoft.VisualBasic
Imports DAL
Namespace BLL

    Public Class AfdelingManager
        Dim ObjDAL As IRSDAfdelingDB = New RSDAfdelingerDB()

        Public Function GetAllRSDAfdeling() As ArrayList
            'Laver Cache af arraylist
            Dim RSDAfdelingerSource As ArrayList = CType(HttpContext.Current.Cache("AllRSDAfdelingCache"), ArrayList)
            If RSDAfdelingerSource Is Nothing Then
                RSDAfdelingerSource = ObjDAL.GetAllRSDAfdeling()
            Else
                HttpContext.Current.Cache("AllRSDAfdelingCache") = RSDAfdelingerSource
            End If
            Return RSDAfdelingerSource
        End Function


    End Class
End Namespace


Codebehind:

Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls
Imports BLL

Partial Class _Default
    Inherits System.Web.UI.Page

    Sub Page_Load()

        Dim DropDownListCache As ArrayList = CType(Cache.Get("AllRSDAfdelingCache"), ArrayList)
        DropDownList1.DataSource = DropDownListCache
        DropDownList1.DataValueField = "Afdelingsnr"
        DropDownList1.DataTextField = "Afdelingsnavn"
        DropDownList1.DataBind()

    End Sub
End Class


ASPX-fil:

<%@ Page Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Import Namespace="System" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContentHolder" Runat="Server">
    Forside - default<br />
   
 
<p>
    <asp:DropDownList ID="DropDownList1" DataTextField="AfdelingsNavn" runat="server">
    </asp:DropDownList>

    <p>
        &nbsp;</p>
</asp:Content>

Håber på hurtig hjælp :-)
Avatar billede Slettet bruger
19. april 2006 - 14:27 #22
Ser det meget underligt ud?
Avatar billede Slettet bruger
19. april 2006 - 14:28 #23
Jeg forestiller mig at jeg enten ikke får puttet noget i cachen eller ikke får det bundet cachen til dropdownlisten??
Avatar billede arne_v Ekspert
19. april 2006 - 14:41 #24
skal

            If RSDAfdelingerSource Is Nothing Then
                RSDAfdelingerSource = ObjDAL.GetAllRSDAfdeling()
            Else
                HttpContext.Current.Cache("AllRSDAfdelingCache") = RSDAfdelingerSource
            End If

ikke vaere

            If RSDAfdelingerSource Is Nothing Then
                RSDAfdelingerSource = ObjDAL.GetAllRSDAfdeling()
                HttpContext.Current.Cache("AllRSDAfdelingCache") = RSDAfdelingerSource
            End If

?
Avatar billede Slettet bruger
19. april 2006 - 14:56 #25
Jo - det er da vist rigtigt. Men jeg får stadig ikke noget i min ddl?
Avatar billede arne_v Ekspert
19. april 2006 - 15:00 #26
Dim DropDownListCache As ArrayList = CType(Cache.Get("AllRSDAfdelingCache"), ArrayList)


skal maaske vaere

Dim DropDownListCache As ArrayList = objBLL.GetAllRSDAfdeling()
Avatar billede Slettet bruger
20. april 2006 - 09:31 #27
Mange tak. Nu virker det. Men med dit sidste forslag, er det så et cache jeg binder til min ddl?

Sender du et svar?
Avatar billede arne_v Ekspert
20. april 2006 - 13:00 #28
binder ? du gemmer bare noget i cache - du skal selv sørge for at opdatere i
cache hvis du ændrer !

og svar
Avatar billede Slettet bruger
20. april 2006 - 13:10 #29
Tak.
Avatar billede Slettet bruger
25. april 2006 - 11:08 #30
Hej Arne_V,

har du ikke lyst til at kigge på dette lille spørgsmål?

http://www.eksperten.dk/spm/705146
Avatar billede arne_v Ekspert
25. april 2006 - 12:53 #31
ok
Avatar billede Slettet bruger
08. august 2006 - 18:05 #32
Jeg må vist hellere få lukket denne her. Arne_v sender du et svar?
Avatar billede arne_v Ekspert
08. august 2006 - 18:54 #33
den er lukket (blaat flag)
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
Kurser inden for grundlæggende programmering

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