webForumDet fria alternativet

Databashantering

147 svar · 8 229 visningar · startad av kristoffer · sida 3 av 8

h0lgerMedlem sedan nov. 2002105 inlägg
#41

Skall försöka ge mig in och skriva C# (kan ej detta så försök se sambanden)

BLS

public class News()
{
	private string _head;

//Här anropar du BODS och en metod som heter t.ex FetchHead

_Head = Test.FetchHeader

	}
	
	public string Head()
	{
		get
		{
			return = _head;
		}
	}
}

Test (som ärver från OleDbData) har metoden som heter FetchHeader

public class Test : Icaaq.Data.OleDbData
	{
public Head FetchHeader{
//Här skickar du in sql statement och exekverar sqlsatsen och får tillbaka en datareader som du sedan läser upp head ifrån och returnerar
string myConnection = Application[”connString”].ToString();
	string SqlStatement = “SELECT blablabla”;
	OleDbDataReader DataReader = RetriveDataReader(myConnection, SqlStatement);
if(DataReader.Read)
	{
		Return Test.DataReader[“newshead”].ToString();
	}
	DataReader.Close();
	
}

}

		public DataReader RetriveDataReader(myConnection, SqlStatement);
		{

			using(DataReader datareader = RetriveDataReader(SqlStatement))
			{
				return datareader;
			}
		}

	}
h0lgerMedlem sedan nov. 2002105 inlägg
#42

Tanken är att inget skikt skall behöva vara beroende av något annat skikts datatyper, objekt, struktur etc.

Tänk att varje skikt skall kunna klara av att man byter ut de andra skikten. I så fall kan man inte skicka sql satser från affärslogiken för vi kanske byter ut sqldatabasen mot en xml fil.

BUL skall validera affärsregler och hämta och spara data. Den skall inte behöva bry sig om vad det är för databas, vad tabellerna heter eller vilka adapters vi använder för att hämta data. Den befattar sig inte med sql satser etc.

BUL vet vad den vill ha för typ av information den struntar i hur och varifrån BODS hämtar informationen.

Klarnar det lite?

icaaqMedlem sedan okt. 20005 273 inlägg
#43

Det klarnar......det gäller bara att få det att fungera med ;)

mvh icaaq

h0lgerMedlem sedan nov. 2002105 inlägg
#44

Som du ser på min C# kod kan jag inte hjälpa dig med det ;)

h0lgerMedlem sedan nov. 2002105 inlägg
#45

Skall uppdatera min kommentar till Pace angående sqlsatser. Man bör egentligen inte lagra sqlsatser i koden överhuvudtaget. Jag rekommenderar att man anropar lagrade procedurer istället från BODS objektet. På så sätt kan man ändra i sql satsen utan att behöva kompilera om.

Har tom sett exempel på där man sparar vilka inparametrar en lagrad procedur vill ha i en xml-fil. På så sätt behöver man inte kompilera om dll:en när man ändrar antalet parametrar och då kan man på ett enkelt sätt ändra parametrarna i den lagrade proceduren utan omkompilering.

icaaqMedlem sedan okt. 20005 273 inlägg
#46

Jag har fått min första 4-skikts procedur att fungera :e Jag återkommer imorron med bevis

ha en trevlig fredagskväll.

mvh icaaq

icaaqMedlem sedan okt. 20005 273 inlägg
#47

Jag och Pace hade en liten disskusion om detta sätt att arbeta och vi såg ingen fördel med att använda 4 st skikt.
Jag har som jag skrev igår fått ihop en fungerande procedur som ser ut som följer(inget optimerat, men det funkar)

[red]
private void loginbutton_Click(object sender, System.Web.UI.ImageClickEventArgs e)
		{
			logIn myLogin = new logIn();
			if(myLogin.login(strUser.Text, strPass.Text))
			{
				HttpCookie myS = new HttpCookie("granted", strUser.Text);
				Response.Cookies.Add(myS);
				error.Text = "Inloggad som "+ Request.Cookies["granted"].Value.ToString();
				strNews.Visible = true;
				strNews.Text = "Skriv en nyhet!";
				newsButton.Visible = true;
				strUser.Text = "";
			}
			else
			{
				error.Text = "Fel";
			}

sen i business

kod:
public class logIn
	{
		public bool login(string user, string password)
		{
			Access dAccess = new Access();
			return dAccess.login(user, password);
		}
	}

sen i Dataaccess

kod:
public bool login(string user, string password)
		{
			string SqlStatement = "SELECT strPassword FROM Users WHERE strUser = '"+user
				+"' and strPassword = '"+password+"'";
			OleDbDataReader DataReader = RetriveDataReader(SqlStatement);
			if(DataReader.Read())
			{
				if(DataReader["strPassword"].ToString() == password)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
			}
			DataReader.Close();
		}
[/red]

men varför inte ge busniess lagret dataaccess på en gång, frågade vi oss?

tacksam för svar

mvh icaaq

PaceMedlem sedan juni 20019 024 inlägg
#48

Ja, som det ser ut nu så skickar man bara data från ett skikt till ett annat.

Hilfe bitte!

h0lger skrev:

Skall uppdatera min kommentar till Pace angående sqlsatser. Man bör egentligen inte lagra sqlsatser i koden överhuvudtaget. Jag rekommenderar att man anropar lagrade procedurer istället från BODS objektet. På så sätt kan man ändra i sql satsen utan att behöva kompilera om.

Det är såklart smidigast, men i mitt fall så får jag nog vänta tills stored procedures kommer till MySQL. :e

kristofferMedlem sedan juni 20001 257 inlägg
#49

Om jag vill binda SQL-data till en DataGrid så kan man skriva så här:

MyDataGrid.DataSource=ds.Tables["Authors"].DefaultView;
MyDataGrid.DataBind();

Hur skall det gå till i en skiktad lösning? Jag vill ju inte hantera DataSets i presentationsskiktet?

h0lgerMedlem sedan nov. 2002105 inlägg
#50

Anledningen till att man inte ger business lagret data access direkt beror på att man vill inte behöva kompilera om businesslagret om man gör en förändring i databasen.

Egentligen bör man lägga sina dbklasser i en egen assembly.

Det bygger på samma princip som säger att du inte skickar ner en referens till t.ex en datagrid till businesslagret. Varje skikt skall kunna gå att bytas ut utan att nåt annat skikt behöver förändras.

h0lgerMedlem sedan nov. 2002105 inlägg
#51

kristoffer -> Ett dataset är egentligen en xml-sträng så det är ok att returnera detta. Alternativet är att ifrån business-skiktet eller fasadskiktet returnera en ren xml-sträng.

icaaqMedlem sedan okt. 20005 273 inlägg
#52

ok.....så jag fortsätter på denna väg....

kristofferMedlem sedan juni 20001 257 inlägg
#53

Och en DataReader är också ok att hantera i presentationsskiktet?

kristofferMedlem sedan juni 20001 257 inlägg
#54

Här är en bra artikel som går igenom hur man bygger en 3-tier applikation: http://www.c-sharpcorner.com/Tutorials/Building3TierAppPA.asp

h0lgerMedlem sedan nov. 2002105 inlägg
#55

Nja, jag tycker inte att en datareader är ok i presentationsskiktet. Det innebär att om du någon gång byter metod för att läsa upp data måste dina klienter (presentationsskikt) byggas om.

kristofferMedlem sedan juni 20001 257 inlägg
#56

Jaha, och hur skulle man då göra om man vill använda en DataReader och en DataGrid? På den här sidan på figur 2 kan man se att det är ok att skicka DataReader till presentationsskiktet.

renholmMedlem sedan apr. 20012 266 inlägg
#57

Visst går det att skicka en DataReader till presentations skiktet, men inte för att c-sharpcorner.com säger att det går. Men jag vill påstå att det är otroligt mycket smidigare att bygga upp classer som innehåller all data. För det första blir den mer fristående från dataskiktet så man kan byta databas utan att påverka resten. Samt att det är väldigt lätt att arbeta med datan senare.

PMedlem sedan jan. 20012 204 inlägg
#58

hmm satta mig ner och kodade ihop denna i vb....

här ligger Data-lagret och Business-lagret (kompilera till Data.dll...)

' --------------
' Data.vb
' --------------

' Namespacen som importeras
Imports System
Imports System.Xml
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration

Namespace Data
    
    
    Public Class DataL 
    
        Dim strCnn as String = ConfigurationSettings.AppSettings("SqlConnect")
        
        Function GetConnection()
        
            Dim Cnn As New SqlConnection(strCnn)
            Return Cnn
            
        End Function
    End Class
    

    Public Class BusinessL 
        Inherits DataL
        
        Public Function GetUserInfo(Id as String)
            'SP här sen...
            
            Dim objCnn As SqlConnection = GetConnection()
            Dim objAdapt as New SqlDataAdapter("SELECT * FROM tbl_test WHERE id = '"& Id &"' ", objCnn)
            Dim objDataSet as New DataSet()
            
            Try 
                objCnn.Open()
                objAdapt.Fill(objDataSet,"UserInfo")
                Return(objDataSet)
                
            Catch Exp as SqlException
                throw Exp
                
            Finally
                objCnn.Close()
            End try
        End Function
    
    End Class
End Namespace

sen i min aspx fil.. som är det "3:e lagret"-presentationen

<%@ Page Language="VB" %>
<%@ import Namespace="Data" %>
<script runat="server">

    Sub Button1_Click(sender As Object, e As EventArgs)
    Dim test as String ="1"
    
    Dim objBusinessL as BusinessL = New BusinessL
    
    DataGrid1.DataSource=objBusinessL.GetUserInfo("1")
    DataGrid1.Databind()
    
    
    End Sub

</script>
<html>
<head>
</head>
<body>
    <form runat="server">
        <p>
            <asp:Button id="Button1" onclick="Button1_Click" runat="server" Text="Button"></asp:Button>
        </p>
        <p>
            <asp:DataGrid id="DataGrid1" runat="server"></asp:DataGrid>
        </p>
    </form>
</body>
</html>

DataL+BusinessL+PresL=3 lager!!
Funkar rätt ok. Ska väl in mer kod osv sen men jaja...Är det något jag skulle behöva ändra/lägga till /ta bort? :q

h0lgerMedlem sedan nov. 2002105 inlägg
#59

Det ser helt ok ut. Personligen hade jag haft ett fjärde lager mellan Business lagret och datalagret. Detta lager hade haft hand om businessobjektets dataccess och hade kompilerats i ett eget assembly. Detta för att slippa blanda in sql kod och liknande i businessobjektet.

En annan fråga till P -> i din aspx fil så gör du denna kopplingen

DataGrid1.DataSource=objBusinessL.GetUserInfo("1")
    DataGrid1.Databind()

Om du nu sätter ditt objBusinessL objekt till Nothing, slutar inte Datagriden att fungera? Man bör ju inte ligga med öppna objekt på detta sätt utan man bör hela tiden jobba Stateless.

Sedan tycker jag inte att databas specifika objekt skall skickas upp till klienten eller presentationslagret. Detta fungerar i väl avgränsade system men om man vill bygga en generell, flexibel arkitektur rekommenderas inte detta. En annan nackdel men en datareader är att den alltid kräver en aktiv,öppen koppling till databasen och det är inte heller att rekommendera.

Det är samma princip som säger att man inte skickar ner en referens till en datagrid till businessobjektet. Varje skikt jobbar med sina objekt.

Detta är mina personliga tankar och erfarenheter.

God jul på er alla i wF.

PMedlem sedan jan. 20012 204 inlägg
#60

Har nu uppdaterat och har nu denna design på det hela(tagit det bästa från olika håll... ;) ):
Klassen DataL: Har hand om databasen
Klassen DataAccessL : Ärver från DataL och har hand om saker så som skapandet av DataSet/DataReader och Update/Instert etc i sql
Klassen BusinessL: Ärver från DataAccess och här finns funktionerna.
Presentationslagret: Skapar instans och presenterar datan etc

Så nu är det alltså 4 lager!

Personligen hade jag haft ett fjärde lager mellan Business lagret och datalagret. Detta lager hade haft hand om businessobjektets dataccess och hade kompilerats i ett eget assembly. Detta för att slippa blanda in sql kod och liknande i businessobjektet.

Har ett 4:e lager nu men har inte kommit ifrån att jag måste ha sql-koden i detta lager... Skulle ju kunna gå att ordna med ett 5:e lager mellan Business och DataAccess eller?

Om du nu sätter ditt objBusinessL objekt till Nothing, slutar inte Datagriden att fungera? Man bör ju inte ligga med öppna objekt på detta sätt utan man bör hela tiden jobba Stateless.

Nja vet inte om det gör det... det verkar inte som det i alla fall... kan ju lösas med att man skapar ett dataset i presentationslagret

    Dim objBusinessL as BusinessL = New BusinessL
    dim ds as dataset = objBusinessL.GetUserInfo("1")
    DataGrid1.DataSource= ds
    DataGrid1.Databind()

En annan nackdel men en datareader är att den alltid kräver en aktiv,öppen koppling till databasen och det är inte heller att rekommendera

Jo men jag använde ett DataSet i min tidigare variant, den har inte en öppen anslutning vad jag har förstått...

Här kommer koden: data.vb

' --------------
' Data.vb
' --------------

' Namespacen som importeras
Imports System
Imports System.Xml
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration

Namespace Data
    
    
    Public Class DataL 
    
        Dim strCnn as String = ConfigurationSettings.AppSettings("SqlConnect")
        
        Function GetConnection()
        
            Dim objCnn As New SqlConnection(strCnn)
            Return objCnn
            
        End Function
    End Class
    
    
    
    Public Class DataAccessL
        Inherits DataL
        
        Public objCnn As SqlConnection = GetConnection()
        
        Function CreateCommand(SqlStatement as String)
            Dim SqlCommand as New SqlCommand(SqlStatement,objCnn)
            Return SqlCommand
            
        End Function
        
        Function RunNonQuery(SqlStatement As String)
            try
                objCnn.Open()
                Dim SqlCommand as SqlCommand =CreateCommand(SqlStatement)
                SqlCommand.ExecuteNonQuery()
            Catch Exp As SqlException
                throw(Exp)
            Finally
                objCnn.Close()
            End Try
        End Function
        Function RetriveDataSet(SqlStatement As String)
            Try
                Dim objDataSet as New DataSet()
                objCnn.Open()
                Dim objAdapt As New SqlDataAdapter()
                objAdapt.SelectCommand = CreateCommand(SqlStatement)
                objAdapt.Fill(objDataSet)
                Return objDataSet
            Catch Exp as SqlException
                throw(Exp)
            Finally 
                objCnn.Close()
            End Try
        End Function    
        Function RetriveDataReader(SqlStatement as String)
            Try
                
                objCnn.Open()
                Dim Command As SqlCommand = CreateCommand(SqlStatement)
                Dim dr As SqlDataReader = Command.ExecuteReader(CommandBehavior.CloseConnection)
                objCnn.Close()
                Return dr
                
            Catch Exp as SqlException
                throw(Exp)
   
            Finally 
                objCnn.Close()
            End Try
            
        End Function
    End Class

    Public Class BusinessL 
        Inherits DataAccessL

        Public Function GetUserInfo(Id as String)
        Return(RetriveDataSet("SELECT * FROM tbl_test WHERE id = '"& Id &"' "))
        End Function
        
        Public Function UpdateUserInfo(Id as String)
        RunNonQuery("Update tbl_test Set password='test' Where id = '"& Id &"'")
        End Function
    End Class
End Namespace

aspx filen

<%@ Page Language="VB" %>
<%@ import Namespace="Data" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.SqlClient" %>
<script runat="server">

    Sub Button1_Click(sender As Object, e As EventArgs)
    Dim test as String ="1"
    
    Dim objBusinessL as BusinessL = New BusinessL
    dim ds as dataset = objBusinessL.GetUserInfo("1")
    DataGrid1.DataSource= ds
    DataGrid1.Databind()
    
    objBusinessL.UpdateUserInfo("1")
    
    End Sub

</script>
<html>
<head>
</head>
<body>
    <form runat="server">
        <p>
            <asp:Button id="Button1" onclick="Button1_Click" runat="server" Text="Button"></asp:Button>
        </p>
        <p>
            <asp:DataGrid id="DataGrid1" runat="server"></asp:DataGrid>
        </p>
        <p>
        </p>
    </form>
</body>
</html>

hmm blev lite kod....
Kommentarer :q :q

141 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
139 ms — hämta tråd, inlägg och bilagor (db)