Link to home
Start Free TrialLog in
Avatar of Eduardo Fuerte
Eduardo FuerteFlag for Brazil

asked on

Could you point how to programatically change an Access database using C#?

Hi Experts

Could you point how to programatically change an Access database using C#?

I'm involved in develop an application that I expect, from time to time, for this to work out, changes in an Access database  must have to be done.

The app is distributed and installed at user's machine. So I need to programatically apply the changes when needed. When a new release is published and installed, and then at the .exe very first run, it automatically find the necessary changes to be made at Access database and do it, making the app runs perfectly.

Thanks in advance.
Avatar of John Tsioumpris
John Tsioumpris
Flag of Greece image

Well how easy is this it depends on the kind of you manipulation you need to perform.If it is on table/query level then you easily "send" CRUD commands to Access to do what you want.
In forms/reports it seems there is a bit more complicated although it there are available "tools" ( Access.Controls, VBIDE.VBComponent,VBIDE.VBProject,VBIDE.Properties) to manipulate them.As a last resort you can use the undocument command "Application.SaveAsText" to export the full definition of your application and perform all kind of manipulation.
The regular approach to this is:
Split your Access application into a "app/client part" and a "backend/server part".
Note that the backend can be either an access database, SQL server db or some other database.

Now distribute the client part to your users (preferably as a accde file, so they can't mess with the code), and when you need to do updates, you simple distribute a new accde file to everyone.
A Version check on startup can ensure that everyone is using the latest version.
You have two options:

1) Updating an existing database. Depending on the kind of changes you need either Access-SQL and/or ADOX.

Caveat: applying changes to an Access database so that the result is an exact copy is under some circumstances not possible, cause not all internals are public accessible.

2) Always deploy the actual version of your database and import the data from the old version.

Caveat: this can be a multistep operation.

And as always: Create backups before applying updates.
Avatar of Eduardo Fuerte

ASKER

Hi for all and thank you for your replies.

ADOX is something similar to MS-SQLServer DDL isn't it?

I guess an approach could be an Access app responsible for all needed table creation, tables' structure changes and so on, no C# codes used for this, am I right?
SOLUTION
Avatar of ste5an
ste5an
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Back to Ander's point:
Is the database split into FE and BE?  If not, why not?  All shared applications should be split as well as any application you create for another person.  I occasionally create apps for my own use that are not split but it would be very poor practice for me to create monolithic apps for the use of others - shared or not shared because it would make updating the application objects very difficult.

Splitting the app allows you to simply replace the FE with an updated version when you want to push out a code update.  When you make schema changes, you can use DAO or ADO to make the changes after first backing up the client's data file.

For my apps that are distributed to the public, I create an Access database with VBA and DAO to update the BE or run scripts should the BE be SQL Server.  But I would NEVER attempt to poke changes into a FE.  In fact, if you distribute the FE as an .accde, you would not be able to update forms/reports/code anyway.
At first sight It looks something really new for me, just a moment to reflect a little.
After a more appurated reading to everyone posts.

The suggestion is to mantain an "app/client part (FE - frontend)" and a "backend/server part (BE)" of Access database, isn't it?

I'm certainly misconcepting concepts but what I catch is:

If the client app (C#) identifies an database version change it automatically asks for download the newer version of database from internet server.

After download,  a mechanism(*) first backups the current database and starts to migrate the current data to the newer database just downloaded. Then the  FE app could start now.

(*)VBA and DAO to update the BE or run scripts should the BE be SQL Server.

Could you check my interpretation?
Ignore the BE/FE part. This is about plain Access-Access applications. Where the UI is also in Access.

Where does SQL Server comes into play now?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@ste5an
I mentioned "SQL Server" only to reinforce my interpretation on what @PatHartman had posted.
It doesn't came into play, sorry. "Ignore the BE/FE part. This is about plain Access-Access applications. Where the UI is also in Access" cleared my overall comprehension.

@Scott
Your considerattions are very closer on what I expect to do since the start. I did it similar with other systems I distributed before, using another tecnology.

In this case it's just a matter of construct a class to deal with the changes needed, basically:  to create a newer table or add new columns to existing tables. Using " Jet/ACE  subset of DDL commands"as you mentioned.

Everytime the C# system starts it checks if it's necessary to actualize Access database.

I guess @ste5an and @Scott approaches are aligned to what I need to do.

Now it's up to me to find "Jet/ACE  subset of DDL commands" to fit my purposes. Maybe you could possibly post an small example on how to do this.
In truth, it looks easy an easy task, I tryed that way, with success.

  public void CriaTabela() // Creates a table
        {
            try
            {
                string strTemp = " [KEY] Text, [VALUE] Text ";
                OleDbCommand myCommand = new OleDbCommand();

                myCommand.Connection = clsConnections.CN;
                myCommand.CommandText = "CREATE TABLE table1(" + strTemp + ")";
                myCommand.ExecuteNonQuery();
                myCommand.Connection.Close();
            }
                 catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        public void CriaColuna() // Creates a column
        {
            try
            {
                OleDbCommand myCommand = new OleDbCommand();
                myCommand.Connection = clsConnections.CN;
                myCommand.CommandText = "ALTER TABLE table1 ADD COLUMN SignIn DATETIME"; 
                myCommand.ExecuteNonQuery();
                myCommand.Connection.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }
    }

Open in new window


User generated image
Thank you for the assistance!