Avatar billede c-sharp Nybegynder
24. januar 2004 - 21:24 Der er 9 kommentarer og
2 løsninger

Design spørgsmål ang. database adgang

Jeg skal til at lave nogle sider i ASP.NET hvor der er en del aktivitet i databasen. Hvordan bør jeg designe mit system, bør jeg lave en fælles klasse der står for alt tilgang til databasen, og hvis ja hvordan kunne en sådan klasse så se ud?
Avatar billede arne_v Ekspert
24. januar 2004 - 21:31 #1
Det vigtigste for performance ved web applikationer og database adgang er at bruge en
database connection pool.

Og det er indbygget i .NET, så det skal du ikke tænke på.

Så er der kode genbrugs aspektet. Hvis du skal bruge den samme
kode mange steder, så er det selvfølgelig smart at lave en utility klasse
som kan bruges alle steder.

Forudsat at du virkeligt sparer noget kode. Der er ikke mange pointe i at
spare N linier med  brug af MS klasser med N linier med kald af dine klasser.
Avatar billede burningice Nybegynder
24. januar 2004 - 21:57 #2
jeg har selv et data-library jeg har lavet med de mest gengsæ funktioner... det kan ikke lave alverdens avancerede gejl, men de mest benyttede ting klarer den snildt.

Da jeg har lavet det så det virker med forskellige slags databaser er det baseret på et interface, samt en factory-class til at returnere den rigtige klasse der svarer til den database man bruger. For at simplifisere error-handling har jeg også lavet min egen DataStoreException der bliver kastet hvis nogle af database-handlingerne fejler.

Interfacet:

using System;
using System.Data;

namespace MPAConsult.ToolBox.Data
{
    /// <summary>
    /// Summary description for IDataStore.
    /// </summary>
    public interface IDataStore
    {
        string Sql
        {
            get;
            set;
        }

        void Close();
        void Open();

        void ExecuteNonQuery();
        void ExecuteNonQuery(bool keepOpen);
               
        object ExecuteScalar();

        IDbCommand GetCommand();
        IDataReader GetReader();
    }
}

DataStoreException:

using System;

namespace MPAConsult.ToolBox.Data
{
    /// <summary>
    /// Summary description for DataStoreException.
    /// </summary>
    public class DataStoreException : System.SystemException
    {
        public DataStoreException(string message, Exception exc) : base(message, exc)
        {
        }

        public DataStoreException(string message) : base(message)
        {
        }

        public DataStoreException() : base()
        {
        }
    }
}

Factory-klassen:

using System;
using System.Configuration;

namespace MPAConsult.ToolBox.Data
{
    /// <summary>
    /// Summary description for DataStoreFactory.
    /// </summary>
    public class DataStoreFactory
    {
        public static IDataStore CreateDefaultDataStore
        {
            get
            {
                string defaultDb = ConfigurationSettings.AppSettings["defaultDb"];
                IDataStore defaultDataStore;

                switch (defaultDb)
                {
                    case "MySql":
                        defaultDataStore = new MySqlDataStore();

                        break;

                    case "MSSql":
                            defaultDataStore = new SqlDataStore();

                            break;

                    case "Odbc":
                            defaultDataStore = new OdbcDataStore();

                            break;

                    case "OleDb":
                            defaultDataStore = new OleDbDataStore();

                            break;

                    default:
                        defaultDataStore = null;

                        break;
                }

                return defaultDataStore;
            }
        }
    }
}

Eksempel på en DataStore (i dette tilfælde MySql):

using System;
using System.Configuration;
using System.Data;
using ByteFX.Data;
using ByteFX.Data.MySqlClient;

namespace MPAConsult.ToolBox.Data
{
    /// <summary>
    /// Summary description for DataStore.
    /// </summary>
    public class MySqlDataStore : MPAConsult.ToolBox.Data.IDataStore
    {
        private MySqlConnection conn;
        private string sql;

        public MySqlDataStore()
        {
            string connStr = ConfigurationSettings.AppSettings["db"];
            conn = new MySqlConnection(connStr);
        }

        public string Sql
        {
            get
            {
                return sql;
            }

            set
            {
                sql = value;
            }
        }

        protected void CheckSql()
        {
            if (Sql == null)
            {
                throw new NullReferenceException("Need to supply SQL-query before executing commands");
            }
        }

        public void Close()
        {
            if (conn.State == ConnectionState.Open)
            {
                try
                {
                    conn.Close();
                }
                catch (MySqlException exc)
                {
                    throw new DataStoreException(exc.Message, exc);
                }
            }
        }

        public void Open()
        {
            if (conn.State == ConnectionState.Closed)
            {
                try
                {
                    conn.Open();
                }
                catch (MySqlException exc)
                {
                    throw new DataStoreException(exc.Message, exc);
                }
            }
        }

        public void ExecuteNonQuery()
        {
            ExecuteNonQuery(false);
        }

        public void ExecuteNonQuery(bool keepOpen)
        {
            CheckSql();

            IDbCommand command = GetCommand();
           
            Open();

            try
            {
                command.ExecuteNonQuery();
            }
            catch (MySqlException exc)
            {
                throw new DataStoreException(exc.Message, exc);
            }
            finally
            {
                if (!keepOpen)
                {
                    Close();
                }
            }
        }

        public object ExecuteScalar()
        {
            IDbCommand command = GetCommand();
            object o;

            Open();
           
            try
            {
                o = command.ExecuteScalar();
            }
            catch (MySqlException exc)
            {
                throw new DataStoreException(exc.Message, exc);
            }
            finally
            {
                Close();
            }
           
            return o;
        }

        public IDbCommand GetCommand()
        {
            MySqlCommand command = new MySqlCommand();
            command.Connection = conn;

            if (Sql != null)
            {
                command.CommandText = Sql;
            }

            return command;
        }

        public IDataReader GetReader()
        {
            IDbCommand command = GetCommand();
            IDataReader reader;

            Open();
           
            try
            {
                reader = command.ExecuteReader(CommandBehavior.CloseConnection);
            }
            catch (MySqlException exc)
            {
                throw new DataStoreException(exc.Message, exc);
            }
           
            return reader;
        }
    }
}
Avatar billede arne_v Ekspert
24. januar 2004 - 22:17 #3
De klasser sparer vist stort set ikke kode i brugen i forhold til standard.

Men du kan skifte database bare ved at rette i konfigurationen.

Og det kan være særdeles praktisk.

Så det er en tredie grund til at lave sin egen klasse: at gøre sin applikation
mindre database afhængig.
Avatar billede burningice Nybegynder
24. januar 2004 - 22:24 #4
arne_v>> tja.. det ved jeg nu ikke... måske ikke det store i besparelse af linjer kode, jeg slipper for det trivielle med at oprette en connection, åbne og lukke den samt try-catch... jeg vil også mene at risikoen for at lave fejl er noget mindre.
Avatar billede arne_v Ekspert
24. januar 2004 - 22:35 #5
Der var ikke noget negativt i min betragtning.

Jeg så bare pointen som at developere kunne unit teste mod f.eks. en Access
database og så kunne koden uden ændringer deployes op mod SQLServer eller
Oracle.
Avatar billede burningice Nybegynder
24. januar 2004 - 22:56 #6
arne_v>> det er rigtigt... jeg bruger det selv, og har da også både OleDbDataStore, MsSqlDataStore og OdbcDataStore liggende
Avatar billede c-sharp Nybegynder
26. januar 2004 - 09:22 #7
Har samt lidt inspiration af cyberfessor's forslag, men jeg kan ikke helt gennemskue koden. Jeg har derfor besluttet at lave min egen database klasse.

I klassen vil jeg lave en metode til at hente data (retunere et resultset) og en metode til at ændre data.

Mit problem er den metode til at hente data, hviket data format skal jeg retunerer data i?
Avatar billede burningice Nybegynder
26. januar 2004 - 13:35 #8
kommer helt an på hvordan dine lag er bygget op... om du henter data'erne direkte fra præsentationslaget, eller om du har noge business-logic inde også. Hvis det første er tilfældet er datareadere og datatables nok det mest brugte.
Avatar billede c-sharp Nybegynder
04. februar 2004 - 17:27 #9
Jeg har leget lidt med Microsoft Application Blocks for .NET. Den kunne jeg godt se nogle fordele i at bruge, den spare min i hvertifal for noget kode.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/daab-rm.asp

Har i nogen erfaring med den?
Avatar billede c-sharp Nybegynder
11. februar 2004 - 06:42 #10
Jeg har valgt at bruge Microsoft Application Blocks for .NET og den virker faktisk ret godt.

cyberfessor: smid et svar så du også kan få del i pointne

også i øvrigt tak for jeres indlæg!
Avatar billede burningice Nybegynder
11. februar 2004 - 13:58 #11
svar
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
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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