Jag är ganska ny när det gäller arkitektur, klasser och lager så jag har några frågor för att komma igång. Det är en ganska enkel sak jag vill åstadkomma men jag vill för en gång skull göra det på ett snyggt sätt. Du vill ha ett enkelt sätt att mappa entiteter (objekt) med din databas? Då finns det verktyg som gemensamt kallas för O/R (Object/Relation) Mapper. Det finns massor av sånna till .NET men en som jag själv använder är NPersist www.npersist.com som är gratis. MYCKET trevligt att arbeta med en O/R Mapper.. kombinera NPersist med ObjectMapper verktyget www.objectmapper.com och du kommer öka din produktivitet och antalet skrivna kod enormt. Får jag bara föreslå att du håller dig till antingen engelska (rekommenderas av mig för att slippa eventuella å,ä och ö-problem) eller svenska. GetAllaForetag låter lite illa i mina öron i alla fall :-) Så här gjorde vi senast och det har funkat väldigt bra:Hjälp med design
Jag har en applikation där jag ska hantera företag mot tabellen tblForetag. Tabellen innehåller fält för bla. Namn, adress, telnr, prislista etc. Jag hade tänkt hantera detta via en datagrid med möjlighet för att lägga till, ta bort och uppdatera.
När jag har jobbat tidigare har jag alltid haft ett projekt i vs.net där jag skapat en Component och i den lagt connection, dataadapter, dataset. Detta har jag gjort med hjälp av designern i vs.net så jag får typade dataset i en xsd fil och vs genererar kod för delete, select, update, insert. Mot min component skapar jag en class där jag lägger metoder för tex, GetAllaForetag() och UpdateForetag(dataset).
Detta är det ända jag gör för att "skikta" applikationen vilket gör att det bli mycket kod i min codebehinde sida för datagridden. Min fråga är hur man ska göra detta på ett snyggt sätt med lager etc och vilka motoder ska ligga i vilket lager.
I min codebehind för att lägga till företag skulle jag bara vilja ha tex.
Dim oForetag as new Foretag
oForetag.add.Namn=tboxNamn.text
oForetag.add.Telnr=tboxTelnr.text.
oForetag.add.save()
eller kanske skapa en foretags collection
oForetag.add(foretagCollectioin)
Hur skulle ni göra? Det jag vill ha med är även tidsåtgången, det kanske går att bygga det kanon snyggt men det tar lång tid och kanske inte är värt det?
/Tomas, som har svamlat om saker han inte känner till :-)Sv: Hjälp med design
Vid intresse skulle kan kanske kunna skriva ihop en artikel inom kort om just detta.Sv: Hjälp med design
Sv: Hjälp med design
Alla dataåtkomstklasser ligger i en egen class library asembly (DLL)
(Add new project.. Class library)
Ex "Foretag"
Alla klasser börjar med
Imports System.Data.SqlClient
Imports Microsoft.ApplicationBlocks.Data
(samt kommentarer om vad klassen gör.)
Data Access Application Block
http://www.microsoft.com/downloads/details.aspx?FamilyId=F63D1F0A-9877-4A7B-88EC-0426B48DF275&displaylang=en
Alla klasser har samma slags metoder: Get, Insert, Update, Delete.
Databasen är SQL server.
All SQL går via stored procedures.
exempel
Public Sub GetGrupp(ByVal GruppId As Integer)
SqlHelper.FillDataset(Params.ConnStr, _
CommandType.StoredProcedure, _
"GruppSel", DsGrupp, New String() {DsGrupp.KFGrupp.TableName}, New SqlParameter("@GruppId", GruppId))
End Sub
Klasserna håller ett typat dataset, ex DsGrupp, (som vi har låtit VS autogenerera på en dummy-sida och sedan har vi kopierat det till vår klass)
Vi använder typade Dataset för att hämta/spara EN post. För att visa listor används SqlDataReader (SqlHelper.ExecuteReader) för prestandans skull, att mellanlagra ett dataset i det fallet är inte bra.
Det betyder att vi slipper skriva en miljard properties som bara håller data in/ut ur databasen men inte fyller nån annan funktion, eller metoder med tiotals inparametrar.
En annan fördel vi får nästan gratis: Systemet ska prata med andra system gemom XML. Eftersom vi har typade Dataset är det en barnlek att extrahera våra olika objekt som XML, eller tvärtom.
"Params" är sytemglobala parametrar som kapslar in t.ex:
System.Configuration.ConfigurationSettings.AppSettings.Get("something")
i form av Public Shared ReadOnly Property
Allt för att underlätta för oss själva och snabba upp arbetet.
Vi försöker återanvända så mycket som möjligt. Grundregeln är: Skriver du ungefär samma kod på två ställen, då skall det göras om till något som kan återanvändas och anropas på båda ställena.. (vi är inte 100% där men målsättningen finns.. :)
För insert/update använder vi:
SqlHelper.ExecuteScalarTypedParams(Param.ConnStr, _
"GruppIns", Me.DsGrupp.KFGrupp.Item(0))
Dvs: vi fyller en rad i en Datatabell och skickar in den raden till ExecuteScalarTypedParams.
Det är en fiffig metod som själv kommer at extrahera StoredProcedure-parametrar som matchar namnen på fälten i DataTabellen (och sedan cachar detta i minnet så det blir i nästa anrop snabbare än att skapa Nya parametrar..)
Detta är inte världens mest avancerade eller optimala designmönster, men enl min erfarenhet mer än tillräckligt bra i 95% av alla fall jag har stött på.
Det två vanligaste misstagen vid systemutveckling:
1. Inget designmönster alls: man får ohållbar spaghettikod och ett system i kaos.
2. Overkill med mönster/metoder/regler: man får en byråkratisk systemutveckling där alla förändringar kostar dubbelt så mycket och tar tre gånger så lång tid.
Knepet är att ligga på 1,5 ;)