h0lgerMedlem sedan nov. 2002105 inlägg Ok, personligen hade jag inte lagt min validering i Code-behind filerna då det finns risk för att man dubblerar valideringen i olika code-behind sidor. (se tidigare kommentar).
Samma sak gäller för formulärsvalideringen. Är lite skeptiskt till denna men jag kan se prestandafördelarna.
PaceMedlem sedan juni 20019 024 inlägg
h0lger skrev:
Ok, personligen hade jag inte lagt min validering i Code-behind filerna då det finns risk för att man dubblerar valideringen i olika code-behind sidor. (se tidigare kommentar).
Samma sak gäller för formulärsvalideringen. Är lite skeptiskt till denna men jag kan se prestandafördelarna.
Jag förstår vad du menar men jag gör inte så. Ta en enkel sak som att kolla om en QueryString innehåller önskat värde, det görs i codebehinden men funktionen som utför valideringen ligger i affärslagret, så det blir ingen som helst dubblering.
h0lgerMedlem sedan nov. 2002105 inlägg Ok då är jag med. Så länge man "centraliserar" funktionerna och enbart har dem på en plats är allt ok.
erkaMedlem sedan dec. 19996 522 inlägg Har en fråga. Jag håller på å bygger en skiktad lösning för ett community nu när jag håller på och lära mig asp.net.
Detta community är updelat i 10 stycken olika delar, tex medlemmar,,nyheter,meddelanden. I min ” Business Data Layer” klass har jag x antal funktioner som returnerar datasets, uppdaterar vissa saker etc . Jag anropar tex min GetNewDataSet i min ” DataAccess Layer” klass. En funktion kan se ut så här
Public Function GetMonthlyNews(MonthNo As Integer,YearNo As Integer)
StrSQL = “sp_ GetMonthlyNews “&MonthNo &”, “& YearNo &””
Return GetNewDataSet(strSQL)
End Function
Det finns en förbannat massa funktioner I denna klass då jag har alla funktioner för att hämta ut data som jag behöver på alla 10 olika delar av communityt I den.
Sedan har jag en ”Affärslagerklass” som innehåller också den en masas funktioner som anropar funktioner inne i ” Business Data Layer” och returnerar något.
Min fråga är följande. Är det smart att dela upp Business Data Layer i flera klasser, en för varje del av communityt. Jag kanske är helt ute och snurrar nu, det är så rörigt bara att ha så många funktioner inne i samma klass.
h0lgerMedlem sedan nov. 2002105 inlägg Du är helt rätt ute med att dela upp ditt BDL i flera klasser. Du bör även göra samma sak för ditt "Affärslager". Denna bör spegla hur din "verksamhet" hänger ihop.
Det bästa är att göra en objektmodell över hur ditt community hänger ihop och sedan implementera denna modell som klasser i Affärslagret.
Därefter rekommenderar jag att du bygger en generell databasklass som innehåller metoder och egenskaper för läsning och skrivning av data till db. Denna generella klass ärver du in i varje BDL klass som du skapar.
Exempel:
Lista alla medlemmar i communityn
ListMembers.aspx -> I On_Load eventet skall alla medlemmar läsas upp
ListMembers.aspx.vb -> Innehåller anropet till Affärslagret för att lista members. Typ clsMembers.ListMembers
Affärslagret -> Håller metoden ListMembers. Anropar "sin" BDL klass dbMembers som håller metoden GetMembers för att lista medlemmar.
BDL: dbMembers -> Ärver från generell db-klass. GetMembers sätter korrekt sql sats och initierar dbconnection samt utför läsningen. Returnerar ett dataset med alla medlemmar till Affärslagret.
Hoppas att du förstår hur jag menar.
erkaMedlem sedan dec. 19996 522 inlägg Tack för svaret, jag är med :)
Allt utom en sak, det har med dll:er att göra men hör lite till tråden också. FÖr att knyta an till ditt exempel, jag kompilerar ListMembers.aspx.vb till en dll som heter Members.dll, men hur ska jag göra med affärslagret och BDL. Ska det kompileras till en enda dll eller flera? Ska varje del av communtiys BDL och affärslager kompileras till enskilda dll:er eller?
h0lgerMedlem sedan nov. 2002105 inlägg Jag hade kompilerat Affärlagret med alla klasser till en dll och BDL-lagret med dess klasser till en dll. Detta för att slippa kompilera om affärslagret om jag går in och ändrar i sql-satser etc (som skall ligga i BDL lagret).
Om du känner att detta inte spelar nån roll för ditt projekt kan du lägga dessa två i samma dll.
erkaMedlem sedan dec. 19996 522 inlägg Ok tack för hjälpen hOlger, jag bifogar en textfil, personligen känns det lite omständigt och att inte allt är korrekt tänkt, men det kanske bara jag som är ovan. Jag ser tex inte någon nytta med att lägga mitt DATA ACCESS LAYER och mitt DATALAYER i 2 olika klasser, men jag kanske har gjort fel därför ;)
Så hur korkat har jag lyckats göra det :)
Tacksam för alla svar
h0lgerMedlem sedan nov. 2002105 inlägg Den såg helt ok ut. :bire Gjorde en förändring i filen. Jag flyttade koden från DataLayer till DataAccessLayer. Du behöver inte ha dessa i två olika klasser.
Känns det mer naturligt nu?
h0lgerMedlem sedan nov. 2002105 inlägg *suck* glömde filen här kommer den
erkaMedlem sedan dec. 19996 522 inlägg Tack hOlger,
Ja lite mer naturligt, vad är det som säger att det kan vara bra att ha de som jag hade det först, alltså som två klasser och inte som en.
h0lgerMedlem sedan nov. 2002105 inlägg Jag har lite svårt att se nån vinst med att ha två klasser istället för en. Det enda som den klassen har är en metod som hämtar en sql connection. Detta kan lika gärna ligga med i den generella data access layer klassen.
Vad anser du själv vara vinsten med två klasser?
erkaMedlem sedan dec. 19996 522 inlägg Enda jag kan se är att man kanske hämtar sin connectionstring från en krypteradfil eller något i den stilen och har funktioner för denna hantering i samma klass som funktionen för att öppna anslutningen, medans man i DataAccessLayer har enbart grejjer för att Accessa olika typer av data och spotta ut rätt saker till andra lager. För att slippa få det så rörigt typ
h0lgerMedlem sedan nov. 2002105 inlägg Då hade jag nog skapat en klass som hanterade kryptering/dekryptering ifall jag önskade läsa/skriva fler saker ned till den krypterade config-filen.
Känns som det blir mer rörigt med två klasser. Med en klass vet du att all databas access inkl. connections sköts i den generella data access layer klassen. Känns lite renare.
Dock behöver det inte var "fel". Om du tycker att det känns snyggare/bättre/så kör på det. I den perfekta objektorienterade världen kanske detta är rätt väg.
erkaMedlem sedan dec. 19996 522 inlägg Ok tack för tankarna. Dock har jag en fråga till, och till p också.
Jag tog mitt exempel för at hämta ett nytt dataset från p's tidigare inlägg, testar ju bara nu. Om du kollar i min tidigare bifogade fil ser du att jag i "Function GetNewDataSet" skapar ett dataset innehållandes sql frågan, sedan i "Function ListAllForums" i "businessLayerForums" skapar jag ett nytt dataset med innehållet från det tidigare dataset'et, det är väll korkat att skapa ett till, man skulle ju kunna skriva
Dim objBusinessL as businessDataLayerForums = New businessDataLayerForums
Return objBusinessL.ListAllForums()
Så man inte skapar 2 datasets, p varför skapar du 2 dataset's, är det en miss ifrån din sida eller har du tänkt på något annat sätt som jag missat.
h0lgerMedlem sedan nov. 2002105 inlägg Så kan du absolut göra. Två fördelar med P´s lösning.
1. Han kan på raden efter sätta objBusinessL till Nothing. Mao objBusiness hämtar alla forum, returnerar Dataset:et till affärslogiken och sedan kan den dö. Då kan man (om man vill) bearbeta dataset:et utan att man behöver låta objBusiness leva kvar. (Prestanda vinst)
2. Det blir lite bättre läsbarhet.
Vad var din tanke P?
PMedlem sedan jan. 20012 204 inlägg :)
1. Prestandard vinst var inte vad jag tänkte på utan jag såg att h0lger hade det sättet i en av de filer han bifogade tidigare så jag kopierade det! Så från min sida var det ingen miss.. :)
2. Bättre läsbarhet? Jag skulle vilja säga att det blir sämre, det är ju jobbigare att instansiera objekt hit och dit...
Nu kör jag helt enkelt:
DataSource = dbCommunity.ShowAllForums - med shared function om det är det du menar?
Sen tycker jag det är lite jobbigt att skriva
Dim objData as New bdCMS()
men jag kanske är för lat!
Bifogar "lite" kod: (med dumma-notepad-kan-inte-hantera-åäö fel)
'********************************************************
' Namn: xxx.Data.DataAccess.vb *
' Innehåll: Databasstruktur *
' Gjort av: EP *
'********************************************************
' Namespacen som importeras
Imports System
Imports System.Xml
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Namespace xxx.Data
'*******************************************************************
' Klassen DataAccess sköter anslutningen till Sql-servern
' samt de generella metoderna som att returnera DataSet, DataReader,
' och NonQuery()
'*******************************************************************
Public Class DataAccess
' Connection
Public objCnn As New SqlConnection(ConfigurationSettings.AppSettings("SqlConnect"))
Function CreateCommand(SqlStatement as String)
Dim SqlCommand as New SqlCommand(SqlStatement,objCnn)
Return SqlCommand
End Function
' Kör en Query mot Databasen
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
' Returnerar Data i form av ett DatSet
Function GetDataSet(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
'Returnerar Data i form av en DataReader
Function GetDataReader(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
End Namespace
'********************************************************
' Namn: XXX.Data.vb *
' Innehåll: Databasstruktur *
' Gjort av: EP '
' + Relaterar till xxx.Data.DataAccess *
'********************************************************
' Namespacen som importeras
Imports System
Imports System.Data
Imports System.Web
Namespace xxxData
'*******************************************************************
' Klassen xxxBusiness(DATA) sköter sql-satser och dylikt för att hämta/ändra
' data. Ärver från DataAccess
'*******************************************************************
Public Class bdCMS 'CMS BusinessData
Inherits DataAccess
Public Function AdminLogin(Username As String, Password as String, Sysid as String)
Dim strSql As String = ("SELECT * FROM tbl_admin WHERE system_id=" & Sysid & "
AND username ='" & Username & "' AND password = '"& Password &"' ")
Return GetDataSet(strSql)
End Function
End Class
Public NotInheritable Class dbCMS ' Business Layer
' **************
' ADMIN
' **************
Public Shared Function AdminLogin(Username as String, Password as String, SysId as String)
Dim objData as New bdCMS()
Return objData.AdminLogin(Username, Password, SysId)
End Function
End Class
End Namespace
:l Kommentarer?
h0lgerMedlem sedan nov. 2002105 inlägg Om du inte har tänkt att "jobba" mer med det som objData.AdminLogin returnerar så är det helt ok. Men om du t.ex. hade velat loopa igenom det som objData.AdminLogin returnerar så hade jag rekommenderat att du hade läst över detta i ett lokalt dataset
Typ så här:
Public NotInheritable Class dbCMS ' Business Layer
' **************
' ADMIN
' **************
Public Shared Function AdminLogin(Username as String, Password as String, SysId as String)
Dim objData as New bdCMS()
Dim dstResult as dataset
dstResult = objData.AdminLogin(Username, Password, SysId)
objData = Nothing
'Jobba vidare med dstResult
.....
'Nu är jag klar med dstResult
Return dstResult
End Function
End Class
Förstår ni min poäng?
PMedlem sedan jan. 20012 204 inlägg Japp... Vad säger du om att använda "Shared Functions" ?
PMedlem sedan jan. 20012 204 inlägg
Pace skrev:
All felhantering hanteras i 3B, främst när man kopplar upp sig till databasen, och slänger iväg ett eget exception med lite information från vilken klass den kom ifrån (t ex "Fel uppstod i Metodensnamn(): Felmeddelande här").
Annars behövs ingen felhantering, för det blir inga fel förutom på detta ställe.
Du har ingen kodsnutt på detta?