Avatar billede fileto Seniormester
02. februar 2004 - 18:23 Der er 10 kommentarer og
3 løsninger

Hvordan skjuler man et object der ikke kan nedarves

Hej

Jeg prøver at gemme refferencen til objectet OleDbConnection  i en class i et namespace så jeg kan reffere den i andres scripts. Fordelen ved dette er at jeg så hvis jeg en dag skal skifte til en odbc database kan endre dette 1 sted i stedet for 1000 steder.

Men jeg har prøvet at lave en class som nedarver OleDbConnection classens  egenskaber men her siger kompileren at OleDbConnection kan ikke nearves.

Findes der en måde at prope denne setning ned i en class for så at kunne referere til den fra andre procedurer :

MDb.DbConnection = new OleDbConnection("min connections treng");

Neden for er vist hvad jeg bruger idag :

public class MDatabase {
          public OleDbConnection DbConnection;
}

void Page_Load(object sender, EventArgs e) {
MDatabase MDb = new MDatabase();
MDb.DbConnection = new OleDbConnection("myconnectionstring");
}

Er der nogen der kan hjælpe med et kode eksempel :-)
Avatar billede arne_v Ekspert
02. februar 2004 - 18:34 #1
I stedet for at arve fra klassen kan du indkapsle den.
Avatar billede arne_v Ekspert
02. februar 2004 - 18:35 #2
Altså du laver en klasse som:
  - har en private OleDbConnection som member
  - har diverse public metoder som kalder tilsvarende OleDbConnection metode
Avatar billede arne_v Ekspert
02. februar 2004 - 18:36 #3
Det er den objekt orienterede måde at gøre det på.
Avatar billede jepsen999 Nybegynder
02. februar 2004 - 18:39 #4
Jeg plejer at lave en klasse DataSettings med en statisk metode:

public static IDBConnection GetConnection(){
  string connectionString = "....";
  // lav oledb connection
  return new OleDbConnection(connectionString);

  // lav sql-server
  // return new SQLConnection(connectionString);
}

Så kan du skrive din pageload:
void Page_Load(object sender, EventArgs e) {
IDBConnection dbConn = DataSettings.GetConnection();
IDBCommand cmd = dbConn.CreateCommmand();
...
}

Du skal altså kun ændre ét sted hvis du vil skifte connectionstring på din oledbconnection eller hvis du vil skifte til sql-server.

Er det det du mener?
Avatar billede arne_v Ekspert
02. februar 2004 - 18:47 #5
Grunden til at du ikke kan extende OleDbConnection er at Microsoft har
puttet attributten sealed på klassen.

Og det har de sikkert en grund til.
Avatar billede arne_v Ekspert
02. februar 2004 - 18:57 #6
Jepsens løsning er iøvrigt også udmærket.

Det er en simpel factory pattern løsning.
Avatar billede fileto Seniormester
02. februar 2004 - 19:22 #7
Tak skal i have
Jeg tygger lige på det. :-)
Avatar billede burningice Nybegynder
03. februar 2004 - 10:19 #8
man kan også lave en kombination af de to... både indkapsling samt et factorypattern. jeg har lavet et lille framework hvor det er muligt at arbejde med forskellige slags databaser uden at man behøver at bekymre sig om det i koden (bortset fra evt. forskelligheder i sql'en selvfølgelig).

Det bygger på et interface, en generel exception, en factory-class og så alle de datastore-class'es man nu engang skulle få brug for.

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();
    }
}

Exception:

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()
        {
        }
    }
}

DataFactory:

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å datastore:

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 fileto Seniormester
03. februar 2004 - 13:09 #9
Hej "Arne v" "jepsen999" og cyberfessor.
Så lykkedes det :-) , tak for hjælpen.
Hvis i vil have point så post lige et svar.
Avatar billede arne_v Ekspert
03. februar 2004 - 14:01 #10
svar
Avatar billede jepsen999 Nybegynder
03. februar 2004 - 16:44 #11
svar
Avatar billede burningice Nybegynder
03. februar 2004 - 22:32 #12
svar
Avatar billede fileto Seniormester
04. februar 2004 - 14:38 #13
Jeg vil sige mange tak til jeg alle 3, jeg er lidt ny i det her så det var godt med alle de mange eksemler. :-)
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