webForumDet fria alternativet

Bygga en egen dbklass

118 svar · 5 015 visningar · startad av Swordfishy · sida 2 av 6

JonMedlem sedan juli 20011 304 inlägg
#21

Jag tycker fortfarande att det låter suspekt ;)
Om du har en liten site, låt oss säge en webbshop.

Då har du ju ett antal sidor, t.ex

Kundens:
Login
Se artiklar
Lägg order
Kassa
Se order
Ändra kunduppgifter

Admin:
Hantera Kunder
Hantera Ariklar
Hantera Order

Sen finns det förståss ett gäng till sidor och hjälpklasser.

Gör du din procedur med dra och släpp på varje sida?

En annan fråga. Nu gäller det ju MySql. Hur löser du det?

GladhMedlem sedan maj 20012 812 inlägg
#22

Ja, jag skule nog vilja säga 99% iaf, möjligen 99,5%
...eller har du tex. stöd för ALLT i ditt DAL som är tänkbart? Exempelvis DataMapping (som nu kanske inte är alltför användbart, men som ändå finns...) ?
[/cita]

Tja.. Mitt DAL skall klara av CRUD. I olika skepnader och med transaktioner både enkla och 2 phase.

övriga finesser tycker jag inte hör hemma i ett DAL. Däremot så kan man lägga lager ovanpå sitt DAL som sköter andra finesser.

Jag tror att ni bör testa adapterns och dataSet:ets möjligheter, det är helt otroligt hur enkelt allt blir med dessa två. följ min beskrivning ovan. Jag lovar, ni säger adjö till SQL och databasklasser fortare än kvickt

Tycker det är underbart att du har hittat en lösning som du trivs med. Min åsikt är dock att datasets är både klumpiga och långsamma och borde förbjudas i all programmering. En riktigt bra O/R Mapper gör precis det dina datasets gör, bara att du får ett optimerad och framför allt ObjectOrienterad lösning.

Ett exempel där DataSets är heltförkastliga är vid Remoting. Att skicka ett vanligt objekt jämfört med ett DataSet via remoting är så mycket snabbare att man nästan kan märkade vid debugning av sin kod.

- Magnus

NöffMedlem sedan nov. 2003569 inlägg
#23

Gör du din procedur med dra och släpp på varje sida?

Nepp nej nej . Jag deklarerar alla dataadapters som public och det typade dataset:et i Global.asax och sen på varje sida lägger jag till följande:

Global myspys=new Global();
DataSet1 datasetet=new DataSet1();

Sisådär nu har jag ett typat dataset plus tillhörande dataadapters på hur många sidor jag vill. för att när du klickar "Generate DataSet" i global.asax så läggs dataset:et "globalt" som ett eget objekt att hämta som DataSet1() på alla sidor . och alla adaptersarna tar man via global klassen ;)

sååå för att fylla dataset:et upprepar jag den vanliga proceduren:

myspys.sqlDataAdapter1.Fill(datasetet);

KLART! :h

JosefMedlem sedan mars 20023 561 inlägg
#24

Verkar inte vara speciellt prestandavänligt tycker jag, Nöff... Jag tror snarare att det är du som borde kolla på vad alla andra använder för lösningar, då kanske det är du som överger auto-genererade dataset o adaptrar så snabbt du bara kan... ;)
Och hur vet du att Swordfishy ens har VS.NET?

SwordfishyMedlem sedan mars 20043 inlägg
#25

Var nog ingen DAL-klass jag tänkte bygga utan snarare en "förenkling av ADO.NET" som fredrik beskrev.

Tanken var att ha allt "databasjobb" i en klass som man sedan anropade och med en funktion lätt kunde utföra select, update, insert, delete frågor..

Typ:

Dim MyCon As New dbklass()

MyCon.Open
MyCon.sqlUpdate("UPDATE Users SET Counter = Counter + 1 WHERE UserID = 99")
myDataSet = MyCon.sqlSelect("SELECT UserID, UserName FROM Users", "dsTableName1")
myDataSet2 = MyCon.sqlSelect("SELECT Price FROM Product", "dsTableName2")
..osv..

Sedan när man är klar med allt man ska med databasen så:

MyCon.Close

Men vid närmare eftertanke så kanske detta bara begränser väldigt mycket? Bättre att köra på:
- spara lösenordet i web.config
- Skriva den kod som behövs skrivas på varje sida som behandlar databasen.

Jag har tyvärr inte VS.NET :/

JonMedlem sedan juli 20011 304 inlägg
#26

Om du har .net framework 1.1 så kan du ta en titt Data Access Application Block for .NET
Dom innehåller hjälpklasser för förenkling av ado.net

Men annars tycker jag att du ska försöka dela upp din applikation i lager (om inte annat för att lära dig).

Ett bra trix är att använda dig av en kodgenerator och kolla på koden. Sen kan man ändra, modifiera och rota runt :)

NöffMedlem sedan nov. 2003569 inlägg
#27

josef

Verkar inte vara speciellt prestandavänligt tycker jag, Nöff... Jag tror snarare att det är du som borde kolla på vad alla andra använder för lösningar,

Varför tror du microsoft skapade dataset för?, för att ingen skulle använda dem?. Och ang prestanda. man kan inte jämföra ett dataset mot en datareader, det är helt olika saker. Du har inte den funktionalitet som ett dataset erbjuder där. Och jag tvivlar starkt på att du kan få högre prestanda och samtidigt exakt samma funktionalitet som ett dataset om du snickrar ihop en egen.

Och det finns heller inget som hindrar dig från att använda datareaders på ett autogenererad adapter:

SqlDataReader reader=global.sqlDataAdapter1.SelectCommand.ExecuteReader();

eller fyll en enklare datatable:

global.sqlDataAdapter1.Fill(datatable);

Så vad är problemet?.

renholmMedlem sedan apr. 20012 266 inlägg
#28

Anledningen till at Microsoft skapat DataSetet är väl att förenkla för programmerare, dock medför oftast förenklingar prestandard problem.

GladhMedlem sedan maj 20012 812 inlägg
#29

Och jag tvivlar starkt på att du kan få högre prestanda och samtidigt exakt samma funktionalitet som ett dataset om du snickrar ihop en egen.

Det har du helt rätt i, och därför bör man vara medveten om när man skall använda vad. Du har ju själv precis insett att ett DataSet är långsammare än en DataReader, varför då envisas med att använda dem, när du ändå knappast använder alla funktioner som finns i de.

De funktioner som du nämner i tråden finns inbygda i O/R Mappers som då ger dig samma enkla/enklare hantering av data till/från databasen till/från objekt. Samtidigt som de ger dig en bättre prestanda.

Varför tror du microsoft skapade dataset för?, för att ingen skulle använda dem?.

För att de är enkla att använd betyder inte att de är rätt att använda dem. Som sagts tidigare så fungerar det på små projekt/applikationer. Det kommer endast medföra problem när man bygger större system där man har en mer ObjektOrienterad programmeringsfilosofi.

Den dan du kommer ditt, så kommer du också inse begränsningarn i att ha sin data i DataSets. Fram till dess så använd dem bäst du vill, men föreslå inte de som någon bra sätt att hämta data från en databas, eftersom de inte är det.

- Magnus

NöffMedlem sedan nov. 2003569 inlägg
#30

Varför jämför du O/R mapper med dataset?, hela den här debatten handlar om hembyggda databasklasser.

Jag har en fråga till dig. Hur löser du följande problem UTAN att anvanda Adapters,Dataset,DataTables?. Alltså du använder din hembyggda databasklass enbart.

skapa upp ett winforms med ett datagrid.
bind grid:et till 1 tabell i databasen.

grid:et ska ha följande funktionalitet:
1. man ska kunna markera multipla rader med musen och trycka Delete på tangentbordet så deleta:s dessa rader i databasen.
2. skriver man i datagridet så uppdateras databasen automatiskt utan någon "UPDATE" knapptryckning.
3. skriver man i datagridet så skapas nya rader automatiskt utan att man behöver trycka på en "NEW" knapp.

kort sagt, datagrid:et ska fungera exakt som Access databas programmet.

p.s med adapters,dataset,tables etc löser man detta med 2-3 rader kod.

GladhMedlem sedan maj 20012 812 inlägg
#31

Varför jämför du O/R mapper med dataset?, hela den här debatten handlar om hembyggda databasklasser.

Det är inte jag som jämför O/R Mappers med dataset det är du, jag säger att dataSet inte bör nämnas i samma mening som O/R Mappers.

O/R Mappers är en utbyggnad av DAL och man bör funderar på att använda en O/R Mapper om man vill programmera ObjektOrienterad och spara sin data i en releationsdatabas.

Jag har en fråga till dig. Hur löser du följande problem UTAN att anvanda Adapters,Dataset,DataTables?. Alltså du använder din hembyggda databasklass enbart.

Det kan jag inte eftersom min O/R Mapper använder sig av DataTable för att hämta data från databasen och fylla mina collections med data.

p.s med adapters,dataset,tables etc löser man detta med 2-3 rader kod.

Det löses inte med 2-3 rader kod, må hända att du själv skriver 2-3 rader kod, men det genereras bra mycket mer kod än 2-3 rader.

Angående de 3 punkterna så löses det på samma sätt som det löses med ett dataset, man kopplar ihop eventen från datagriden till att utföra kommandon till de klasser som skapas med hjälp av O/R Mappern, skulle gissa att varje event skulle ha mellan 3-30 rader helt beroende på hur kompakt jag vill skriva min kod (alltså hur läsbar den blir). Alltså skulle det lösas med typ 15-20 rader kod (förutom de autogenererade eventfunktions stubbar som VS.NET skapar till mig).

Det intressanta är inte om jag skriver mindre kod, det kommer jag aldrig att göra, eftersom min O/R mapper inte är knuten till .NET som ett dataset är. (av förklarliga skäl).

Det intressanta är istället den prestandavinst och underhållseffekter jag får genom att skapa klasser som innehåller både logik och regler.

Uttöka ditt exempel till att du skall börja kontroller den data som du matar in, det kanske är så att om du matar in en stad, så skall det automatiskt hämta landet där staden ligger i. Man kanske skall kontrollera om datumet som man fyller i, är gilltigt mot en databas som innehåller giltiga datum.

Med din lösning, så måste du skapa lösaklasser för att hantera dessa regler, medans jag kan lägga in dessa regler för just den klass som det gäller (typ personnummer kontrol, läggs i class Person) osv osv.
Tänk sedan att du har 2 olika applikationer som använder sig av samma Person tabell i databasen, då har jag 1 dll som innehåller data och logik för denna tabell. I ditt fall så måste du skapa all logik 2 gånger för kontrollera så att det blir exakt samma information som hämtas/kontrolleras/lagras. Detta är en mardröm eftersom för eller senare kommer dessa 2 kodsnuttar att komma ursync. Du måste också skapa och koppla dina datasets 2 gånger. Jag importerar mitt DLL och kan använda min klass enkelt i mina 2 eller flera applikationer. Så för varje applikation som använder sig av ett Person objekt, så ökar du din risk att något blir fel, speciellt om du måste ändra på något så har du många ställen att ändra på. Medans jag har 1 ställe att ändra på och detta slår igenom för alla applikationer.

Det är där vinsten ligger med en O/R Mapper. Man får ett tydligare flöde i sin kod, vilket underlättare utbyggnad och underhåll av sin kod.

Jag vet att du har svårt att inse dessa fördelar eftersom du inte håller på med stora applikationer (du kommer väl ihåg att du berättade för mig att min applikation bestod av 1 klass). När du börjar bygga stora applikationer så inser du att det är ohållbart att hålla på med datasets i en OOP miljö.

- M

PDahlenMedlem sedan apr. 2004778 inlägg
#32

Tycker att det här har varit en rätt kul diskussion att följa. Det är intressant att se hur många olika infallsvinklar det finns för att lösa problem.

Nu tänkte jag dela med mig av mina egna tankar.

1. Vad är det egentligen Swordfishy är ute efter?
Min tolkning:
En generell klass som sköter kopplingen till databasen, dvs. ett Data Access Layer.
Jag tycker att det är konstigt att det bara är en person som nämner Data Access Application Block
Varför bygga en egen när MS redan har gjort det?
MS-DAL sköter alla kopplingar mot databasen. Du skickar in en sql-koppling, namn på en lagrad procedur och om nödvändigt sqlparametrar.

2. En fråga till Nöff.
Det verkar som att du är väldigt inriktad på hur snabbt du får in databasresultat i dina sidor, men jag håller nog med Gladh att du skulle kolla lite på prestandan.
Vet inte om jag förstått dig rätt, men du slänger alltså in alla dina tabeller och så plockar du med de resultat du behöver? Men använder du inte Stored Procedures? Det är nummer ett om du vill ha en snabb applikation.

3. Objektorienterat
Med .NET så kan man äntligen koda OOP på "riktigt" när man bygger en webbapplikation. Det tycker jag är en av de stora fördelarna med .NET.
För min del så innebär det att jag kan återanvända större delen av mitt arbete i alla mina projekt. Om jag ändrar något i en klass så gör jag det på ett ställe, kompilerar om alla projekt som använder klassen och så är det klart.
Jag kan till och med återanvända klasserna till desktopapplikationer.
Gladh pratar om O/R mappers. Har själv inte använt dessa mer än provat på men jag ser definitivt fördelen av det i stora projekt. Själv så är jag än så länge ett för stort kontrollfreak, tyvärr ska jag väl tillägga, och vill göra allt själv.

4. Min lösning
Jag bygger mina webbapplikationer helt objekt-orienterat. I vissa fall så är oop i .NET inte riktigt på samma sätt som "klassisk" oop med t.ex. C++, inte i mitt huvud i alla fall.
Jag har i alla fall följande:
- Datalager
-- En SQL Server 2000 databas

- Data accesslager
-- Stored Procedures i databasen
-- MS DAL som sköter alla anrop

- BusinessLogik
Detta lager har jag indelat i två olika lager
-- 1. Klasser som sköter anropen och omvandlar databasresultaten till objekt.
--- 2. Objekt som är resultat av punkt 1.
På detta sätt behöver mina objekt och presentationslager inte veta något om hur den underliggande databasen ser ut.

- Presentationslogik
-- Code-behind i .aspx sidorna

- Presentationslager
-- .aspx sidor och webbkontroller.

Eftersom jag använder Visual Studio .NET så blir det ännu enklare att återanvända klasserna.
Ett exempel:
Jag skapar mitt webbprojekt.
I min solution lägger jag till klassprojekt, t.ex. ett för Produkter.
Produkter är ett Class Repository som innehåller alla klasser som hanterar allt som har med produkter att göra. T.ex. som finns det BusinessLogik klasser, produktklasser och productcollections, m.m.
Samma projekt Produkter kan jag använda när jag bygger nästa webbprojekt. Det är bara att lägga till det i min solution.

Det blev ett långt inlägg det här men det brukar bli så när det är något jag själv tycker att jag har koll på.

Hoppas i alla fall att det hjälper någon.

PMedlem sedan jan. 20012 204 inlägg
#33

Intressanta disskusioner som alltid. Byggde en liknande "DAL" för nästan ett år sen nu och har inte behövt ändra den nämnvärt. Det jag också försökte väva in var att jag enkelt ville kunna byta mot olika databaser, främst därför att jag använda Mysql då. Man förlorar ju en del med SP men det kan det vara värt om projekten inte är alltför stora.

Vill trycka lite extra på "datatable". Tycker det är ett underbart sätt att hantera data på. Snabbt och enkelt och kan lätt vävas ihop med DataSetet om man behöver flera funktioner...

PDahlenMedlem sedan apr. 2004778 inlägg
#34

Just det här med möjligheten att kunna byta databas är en sak som är enklare med objekt-orienterad och n-tier programmering.
Om jag t.ex. skall byta från SQL Server till MySql så byter jag ut mitt DAL och så kanske jag behöver fixa några ändringar i Business Logic lagret.

Du skriver att "man förlorar en del med SP". Förstår inte riktigt vad du menar. Prestandamässigt är det ju bättre att göra saker i sin SP än i koden.

cyprysMedlem sedan dec. 20003 563 inlägg
#35

Än så länge arbetar jag inte med några större webbprojekt och har inga planer på att starta något bara "for the heck of it". Men för att förstå hur jag borde närma mig ett sådan projekt hur borde man tänka?

I dagsläget arbetar jag med en DataBaseConnection.vb som ser ut i stora drag:

Imports System.Data.OleDb
Imports System.Data

' skapar namnrymd för databasanrop
Namespace DataBaseConnection
    ' skapar klass för databasanrop
    Public Class DataLayer
        ' hämtar in sträng för uppkoppling mot databas från web.config
        Public defaultDataConnection As New OleDbConnection(ConfigurationSettings.AppSettings("DefaultDataConnection"))

        ' skapar ett sql-kommando utifrån en sträng
        Private Function CreateCommand(ByVal sqlStatement As String) As OleDbCommand
            Return New OleDbCommand(sqlStatement, defaultDataConnection)
        End Function

' funktioner för scalar, reader, dataset och nonquery här nedan

Sedan har jag ytterligare ett lager med olika klasse för hantering av olika delar i mitt projekt. Som exempel forum, personuppgifter meddelanden eller vad som helst egentligen. Alla dessa ligger i stort sett i varsin .vb-fil.

I dessa klasser för t.ex. personuppgifter skulle jag kunna ha en funktion för att hämta e-postadressen för ett id man skickar in. I detta fall använder jag oftast scalarReader.

Men om jag skulle vilja hämta ut ett gäng personer med dess uppgifter och lägga det i en tabell?
Där gör jag i dagsläget att jag i parsonhantering.vb anropar DataBaseConnection och hämtar ett dataset som jag sedan skickar vidare till CB-lagret. Och det är här jag fattat att man kan göra vinningar genom att helt skippa dataset? Hur skulle man på bästa sätt göra prestandavinningar här?

Såhär? Att istället för att hämta ett dataset så hämtar man en datareader till personhantering.vb och fyller en datatable själv och skickar därefter en datatable till CB.
Är detta ett bättre sätt?
Borde man inte då kunna automatisera att lägga in datareadern i en datatable?

Lite allmänna frågor helt enkelt. :)

* edit * fortsättning *

Säg att jag vill hämta alla epostadresser jag har i en tabell. Jag ser ingen större skillnad på dessa två rent prestandamässigt förutom att nr 2 känns smått enklare att arbeta med.

Function GetAllEposts1()
        Dim objData As New DataBaseConnection.DataLayer

        Dim dt As New DataTable("test1")
        dt.Columns.Add("Epost")

        Dim dr As OleDb.OleDbDataReader
        dr = objData.GetDataReader("select epost FROM accounts ORDER BY id DESC")

        While dr.Read
            Dim drow As DataRow = dt.NewRow()
            drow(0) = dr(0)
            dt.Rows.Add(drow)
        End While

        dr.Close()
        objData.defaultDataConnection.Close()
        Return dt
    End Function

    Function GetAllEposts2()
        Dim objData As New DataBaseConnection.DataLayer
        Return objData.GetDataTable("select epost FROM accounts ORDER BY id DESC")
    End Function

Borde inte nr2 vara bättre i detta fall. Den använder sig väl av nästan samma metod som nr 1?

PMedlem sedan jan. 20012 204 inlägg
#36

PDahlen skrev:

Just det här med möjligheten att kunna byta databas är en sak som är enklare med objekt-orienterad och n-tier programmering.
Om jag t.ex. skall byta från SQL Server till MySql så byter jag ut mitt DAL och så kanske jag behöver fixa några ändringar i Business Logic lagret.

Du skriver att "man förlorar en del med SP". Förstår inte riktigt vad du menar. Prestandamässigt är det ju bättre att göra saker i sin SP än i koden.

Skrev lite fel, skulle precis vara att du vinner på det istället. Men om du nu skulle byta till låt oss säga mysql, hur använder du då SP? Mysql har väl i dagsläget inget stöd för detta.

emissionMedlem sedan dec. 19996 721 inlägg
#37

Men om du nu skulle byta till låt oss säga mysql, hur använder du då SP?

Det är där DAL:et kommer in. SQL Server-versionen utnyttjar SP, medan MySQL-versionen får lösa samma uppgifter utan SP. Huvudsaken är att det är transparent för överliggande lager.

VimpMedlem sedan juli 20022 537 inlägg
#38

P skrev:

Men om du nu skulle byta till låt oss säga mysql, hur använder du då SP? Mysql har väl i dagsläget inget stöd för detta.

Har hört att MySQL 5 kommer ha stöd för SP :bire

PDahlenMedlem sedan apr. 2004778 inlägg
#39

Ja, mySQL 5 kommer att ha stöd för SP.
Men precis som emission säger, eftersom man har sina olika lager så kan man bygga lösningar för alla databaser.

Använder som sagt Microsofts Data Access Layer för databaskopplingen. Ovanför detta har jag ett Business Logic lager som omvandlar databasresultatet till starka typer. Detta gör att om jag ska byta till mySQL byter MS DAL till ett DAL som hanterar mySQL. Jag bygger sedan ett extra Business Logic som hanterar mySQL.

Jag får nog tillägga att vi har lite olika benämningar på saker och ting. Jag tror att det några av er kallar DAL är mitt DAL och BL tillsammans.

** Ett tillägg **
Jag la upp en lite mer utförlig beskrivning på det jag pratade om i mitt första inlägg på min blog, pdc.se/blog/DisplayEntry.aspx?eid=5

NöffMedlem sedan nov. 2003569 inlägg
#40

Min åsikt är att datasets är klumpiga och långsamma och borde förbjudas i all programmering.
En riktigt bra O/R Mapper gör precis det dina datasets gör, bara att du får ett optimerad och framför allt ObjectOrienterad lösning.
Du har ju själv precis insett att ett DataSet
är långsammare än en DataReader, varför då envisas med att använda dem, när du ändå knappast använder alla funktioner som finns i de.De funktioner som du nämner finns inbygda i O/R Mappers som då ger dig samma enkla/enklare hantering av data till/från databasen till/från objekt. Samtidigt som de ger dig en bättre prestanda.Enligt min åsikt så skall ett objekt typ, Customer, innehålla både logik och data. Vilket då gör att en O/R Mapper är att föredra framför användadet av DataSets.

Jag gjorde jämförelser mellan VS.NET inbyggda funktioner och hembyggda databasklasser som jag skrivit gång på gång. men visst kan jag visa vad man kan göra med ett dataset, se nedan.

Det kan jag inte eftersom min O/R Mapper använder sig av DataTable för att hämta data från databasen och fylla mina collections med data.

Då kanske jag kan upplysa dig om att ett dataset är en collection av just Datatables. Och jag frågade dig hur du löser det med en hembyggd databasklass, inte en autogenererad O/R mapper!.
Och om du tittar närmare på det enorma klassbibliotek som genereras av din O/R mappern, vad hittar vi i dem?
jo, vanlig ADO.NET teknik förstås, såsom DataTables,DataRelation,DataRows,DataColumn,DataAdapters, SqlCommand.
Precis vad ett dataset också består av.
Är inte det att kasta stenar i glashus?.

Det löses inte med 2-3 rader kod, må hända att du själv skriver 2-3 rader kod, men det genereras bra mycket mer kod än 2-3 rader.

vad gör då inte en O/R mapper?, skapar ett klassbibliotek åt dig såklart.
skönt att du börjar inse att det inte är fel att använda applikationer som skriver koden åt dej.
Och är du inne på den banan hur mycket kod som genereras kan du också spekulera hur mycket kod som som skapas när du använder en Button klass, det är ganska irrelevant. Det som är relevant är hur mycket kod JAG behöver skriva. Och den inställningenborde varje programmerare ha. Annars kan vi lika gärna gå ner på assemblernivå och programmera, där har du prestanda.

Utöka ditt exempel att du skall börja kontroll den data som du matar in, det kanske är så att om du matar in en stad, så skalldet automatiskt hämta landet där staden ligger i.

På sid.1 gav jag en beskrivning hur man skapar relationer i ett dataset. och där kan du automatiskt hämta hur mycket du vill från andra sammanvävda tabeller.
Sen har jag en fråga till dig, hur skapar du 2 NÄSTLADE DATALIST med 2 sammanvävda tabeller utan att använda Dataset:ets DataRelation objekt.

måste du skapa lösaklasser för att hantera dessa regler, medans jag kan lägga in dessa regler för just den klass som det gäller(typ personnummer kontrol, läggs i classPerson.Tänk sedan att du har 2 olika applikationer som använder sig av samma Person tabell i databasen,då har jag 1 dll som innehåller data och logik för denna tabell. I ditt fall måste du skapa all logik 2 gånger för kontrollera så det blir exakt samma information som hämtas/kontrolleras/lagras. Det är en mardröm för eller senare kommer dessa 2 kodsnuttar att komma ursync. Du måste också skapa och koppla dina datasets 2 gånger.Jag importerar mitt DLL och kan använda min klass enkelt i mina 2 eller flera applikationer. Så för varje applikation som använder sigav ett Person objekt, så ökar du din risk att något blir fel, speciellt om du måste ändra på något så har du många ställen att ändra på.Medans jag har 1 ställe att ändra på och detta slår igenom för alla applikationer.

Vilket dilerium. Jag tror det är dags att jag lär dig lite avancerad DataSet hantering.
När man skapar ett typat dataset i VS.NET skapas en fristående dataset1.cs fil om du tittar i din projektmapp.
Denna .cs är källkoden till det typade dataset:et. Och i denna dataset klass kan man helt ändra om dataset:et från grunden om jag vill det, ändra metoderna, egenskaperna,
lägga till nya egenskaper/metoder införa lite skön logic och kontroll etc.
Men hursomhelst, här lägger jag till raderna SqlDataAdapter.Fill(this.kunder); SqlDataAdapter2.Fill(this.produkter); i konstruktorn för då slipper jag helt dataadapters
eller command objekten när jag använder dataset:et.
Och i OnRowChanged,OnRowDeleted,AddkunderRow eventsen lägger jag kontrollen av indatan på den tabell jag vill kontrollera samt Adapters (eller om jag vill, bara command objekten) för UPDATE/DELETE/INSERT.
och så kompilerar jag den till en .DLL fil.

Alltså, jag har sammansmällt adaptern, logic, dataset:et till en enda klass. Men det är inte nödvändigt att slå ihop allt till 1 enda klass utan man kan göra lite som man vill.
bara ha indata-kontrollen i dataset:et och adaptern för sig om man vill, eller splitta upp datatabellerna, det är upp till en själv. Men jag gillar att ha allt på samma ställe.

Nu har vi ett typat DataSet.DLL som innehåller följande.
1. Alla adaptrars som behövs vid UPDATE,SELECT,DELETE. Och dessa adaptrar anropas automatiskt ifall något förändras i DataSet:et.
2. Alla relationer tabeller sinsemellan finns i dataset:et, och kan användas ifall vi ska använda nästlade datalist:s
3. Alla kolumner i tabellerna har rätt datatyper, (ger compiletimefel istället för runtimefel).
4. All kontroll av indata som läggs in i databasen finns i datatabellernas event.
5. Dataset:et fyller sig själv vid instansiering.
6. Ändrar man dataset:et i runtime ändras databasen samtidigt.

Och hur går det nu till när man använder detta?, jo, enligt följande:
DataSet1 mittdataset;
först instansiera DataSet1 klassen i page_load:
mittdataset=new DataSet1(); //Nu fylls dataset:et automatiskt med tabellerna i databasen istället för att jag måste göra det med "SqlDataAdapter.Fill(mittdataset.kunder);"
DataGrid1.DataSource=mittdataset.kunder; //Bind kunder-tabellen till ett datagrid
DropDownlist1.DataSource=mittdataset.produkter; //Bind produkter-tabellen till en dropdownlist.

Och vill jag tex visa produkterna som varje kund beställt skapar jag bara 2 nästlade datalists och RITAR upp relationen i "View Schema" i VS.NET, (innan jag kompilerar klassen förstås)
DataSource är namnet på datarelationen.
<asp:datalist id="DataList1" runat="server">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "namn") %>
<asp:DataList ID="DataList2" Runat="server" DataSource='<%# DataBinder.Eval(Container.DataItem, "myrelation2") %>'>
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "produktnamn") %>
</ItemTemplate>
</asp:DataList>
och slutligen i koden:
DataList1.DataSource=hej;
DataList1.DataBind();
Så letar den själv upp vilka tabeller som hör till vilka.

Och vill jag uppdatera något i databasen ändrar jag bara i dataset:et utan något anrop för att aktivera databasen, eftersom eventet gör det automatiskt som såhär:
mittdataset.kunder[0].namn="olle";
Och för att dra ett exempel om vi har ett editerbart webdatagrid, så det enda jag behöver göra i update händelsen på datagrid:et är detta:
mittdataset.kunder[e.item.itemindex].namn=((TextBox)e.Item.Cells[4].Controls[0]).Text.Trim()
DataGrid1.DataSource=mittdataset.kunder;
DataGrid1.DataBind();

eller om det gäller winforms datagrid lägger jag till följande rad i datagrid:ets händelshanterare för cellerna:

DataGrid1.SetDataBinding(hej.kunder,null); //det är inte mer, bara med denna rad inkluderar jag ALLT som jag skrev i mitt förra inlägg, det som Gladh behövde 15 rader på sig för.

i och med att jag ändrar ett row i en av dataset:ets tabeller så anropas händelsen OnRowChanged automatiskt i dataset:ets tabell där jag la all logic och update-adaptern,
som först kontrollerar så jag inte försöker stoppa in konstiga saker i datatable:t och efter kontroll lägger in det ändrade värdet i databasen. Och samma sak med OnRowDeleted,AddkunderRow, jag behöver inte förklara mer där tror jag.
Asså, förstår ni vad jag menar??, tänk er ett datatable, ändrar ni datatable:t så ändras databasen samtidigt, synkroniserat.
utan att jag behöver anropa någon "update" metod eller liknande. Och dataset klassen kan jag återanvända hur mycket jag vill eftersom det är en Klass. Och nu kommer vi till frågan ni ställer er, vad tungt det måste gå?. Vadå?, hade du splittat
upp dataset:ets commandobjekt/adaptersarna i din kod istället hade det blivit lika mycket. För du använder förmodligen ett command objekt för att exekvera SQL till databasen? . Och du använder förmodligen en adapter för att fylla ditt datatable, och använder du inte en adapter för att fylla ett datatable så görs det manuellt med att dra ur ett SchemaTable ur en datareader och bygga upp datatable:ts DataColumner,DataRows med den,
och efter det fylls datatable:t med .NewRow() metoden på datatable:t, så det är precis samma sak.

Och O/R mappern fyller också datatable:s likadant som en adapter fyller ett datatable i ett dataset.
Enda skillnaden mot ett dataset är att man med O/R mappern kan ta ur varje tabell för sig när man vill jobba med den.

Men det går alldeles utmärkt att göra detta med dataset:et också. Eftersom alla datatable:s i dataset:et är färdiga klasser med "internal" deklarerat, ändra det till "public"
så kan du instansiera ur varje datatableklass för sig:
DataSet1.kunderDataTable kunder=new DataSet1.kunderDataTable();
Så får man en mer objektorienterad filosofi.
Och därmed ökar prestandan eftersom man kan välja vilka tabeller i dataset:et man vill jobba med, så man inte har alla tabeller i minnet samtidigt.

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