Visual Studio 2012 C# Connecting to an Access DB

Posted on Sunday, February 17, 2013



I have a need in a new program I am creating to talk to an Access DB.   I am programming in C# using Visual Studio Pro 2012.
I am using InstallShield LE for my installation process.   If you are having problems getting InstallShield LE working on Visual Studio I did a little write up on it here http://www.whiteboardcoder.com/2013/02/visual-studio-pro-2012-install-shield-le.html  





First a few Gotchas


Before I get into the programming I want to list a few gotchas that I had to deal with.  I hope this saves you some programming time before you start.

My first gotcha is a dump one, I don't create databases all that often so I foolishly named my table "Names" which is an SQL reserved word.  I knew this in the back of my head but it's been so long since I made an example simple database I had forgotten….

My second gotcha is at least a little more impressive…

I have a 64 bit version Win 7 running on my Box.   I have Office 2010 installed and running as 32-bit programs.  If you want to check if your office suite is 32-bit or 64-bit check this guide http://www.howtogeek.com/howto/24259/beginner-discover-if-youre-running-the-32-or-64-bit-version-of-office-2010/ [1] 

By Default my Visual Studio 2012 C# program is set to compile to Any CPU  (I am guessing 32-bit or 64-bit).   As a result if I try to compile my program and connect to a database I get this error.





The error "The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine." Is caused by the program trying to find a 64 bit connection and not finding it, since in my case there is only a 32-bit one.  


There seems to be two ways to fix this.

The first way is to go to http://www.codeproject.com/Tips/370922/Microsoft-Access-Database-Engine-2010-Redistributa [2] download and install this program that will then be able to handle 64-bit connection and 32-bit connections.

The second way involves fixing Platform target of your program.





From Visual Studio 2012 select Build--> Configuration Manager





Change "Any CPU"  to x86 and click Close.  This forces the issue and uses the 32-bit connection type.

This is the solution I chose, as for my client it's one more thing they need to install before they can use the software.




Programmatically Accessing the Database



I am starting with a basic "Hello World" Program I made before.  (if you need help with getting that working here is the details http://www.whiteboardcoder.com/2013/02/visual-studio-pro-2012-install-shield-le.html 


I am editing a button click.  So that when the button is clicked it will read from a table called "Employees" in my database that is located on my Desktop.


Here is the code.


        private void button1_Click(object sender, EventArgs e)
        {
       
            String connectionString =
                  @"Provider=Microsoft.ACE.OLEDB.12.0;Data"
                + @" Source=C:\Users\patman\Desktop\Test_DB.accdb";
            String tableName = "Employees";
            String query = String.Format(
                          "select * from [{0}]", tableName);
            DataSet ds = new DataSet();
            OleDbConnection conn =
                  new OleDbConnection(connectionString);

            try
            {
                //Open Database Connection
                conn.Open();

                OleDbDataAdapter da =
                         new OleDbDataAdapter(query, conn);

                //Fill the DataSet
                da.Fill(ds, tableName);
                conn.Close();

                MessageBox.Show(" Hello World "
                       + ds.Tables["Employees"].Rows.Count
                       + "  "
                       + ds.Tables["Employees"].Rows[0]["id"]
                       + "  "
                       + ds.Tables["Employees"].Rows[0]["fname"]
                       + "  "
                       + ds.Tables["Employees"].Rows[0]["lname"]);
            }
            catch (OleDbException exp)
            {
                MessageBox.Show("Database Error:"
                                 + exp.Message.ToString());
            }
            finally
            {
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
            }
        }



First the connection string to my database is
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\patman\Desktop\Test_DB.accdb

I query it to get all the data from tableName.  It then fills the DataSet ds with the all the data from this table.  Then it create a MessageBox do display the first row of the query results the column called fname.





Looking at Employees Table in my test database you can see that the first record in the fname column is "Fred"






Now if you run the program and click the "Hello World Button"  you will see that it does grab the data from the database and display it.






In fact I can update the database while the program is still running, changing Fred to Lisa, and because in this case it always queries the database every time the button is pressed the results will update.




And the results are updated the next time you click on HelloWorld.





Updating ACCESS Database



Now that we can successfully read from an ACCESS database how about adding records to the database in C#

The first step is to update the DataSet.  Here is my code that updates the information in the first Row of the Dataset.   I also updated the code here to explicitly close the connection to the database.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace HelloWorld
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            String connectionString =
                  @"Provider=Microsoft.ACE.OLEDB.12.0;Data"
                + @" Source=C:\Users\patman\Desktop\Test_DB.accdb";
            String tableName = "Employees";
            String query = String.Format(
                          "select * from [{0}]", tableName);
            DataSet ds = new DataSet();
            OleDbConnection conn =
                  new OleDbConnection(connectionString);

            try

            {
                //Open Database Connection
                conn.Open();
                OleDbDataAdapter da =
                       new OleDbDataAdapter(query, conn);
                OleDbCommandBuilder cmdB =
                       new OleDbCommandBuilder(da);
                da.MissingSchemaAction =                
                       MissingSchemaAction.AddWithKey;

                //Fill the DataSet
                da.Fill(ds, tableName);

                //-------- Update the first Row ---
                ds.Tables["Employees"].Rows[0]["fname"] = "Steven";
                ds.Tables["Employees"].Rows[0]["lname"] = "Bailey";
                da.Update(ds, "Employees");
                //-------- Update the first Row ---

                //Close the Database Connection
                conn.Close();

                MessageBox.Show(" Hello World "
                       + ds.Tables["Employees"].Rows.Count
                       + "  "
                       + ds.Tables["Employees"].Rows[0]["id"]
                       + "  "
                       + ds.Tables["Employees"].Rows[0]["fname"]
                       + "  "
                       + ds.Tables["Employees"].Rows[0]["lname"]);
            }
            catch (OleDbException exp)
            {
                MessageBox.Show("Database Error:" + exp.Message.ToString());
            }
            finally
            {
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
            }
        }
    }
}







 

The first record of my Database contains Jefferey Jones, but If I run this program


 


I can see that the DataSet was updated with the new fname and lname.





This also updated the database




If you look at this part you can see the DataSet (ds) being updated with the new information.  However this does not get applied to the Database until you use da.Update(ds, "Employees")






For the update to have worked you need to have a OleDbCommandBuilder applied to the OleDbDataAdapter as show here.



Inserting into a Database (adding Rows)




     DataRow row = ds.Tables["Employees"].NewRow();
     row["fname"] = "Patrick";
     row["lname"] = "Bailey";
     ds.Tables["Employees"].Rows.Add(row);
     da.Update(ds, "Employees");




Use this bit of Code to add a row to the DataSet then update the DataSet back to the Database.



Deleting Rows from the Database




        //------ Delete a row ----
        ds.Tables["Employees"].Rows[0].Delete();
        da.Update(ds, "Employees");
        //------ Delete a row ----





Use this bit of Code to delete a row from the DataSet then delete that row from the Database.




That concludes this tutorial on Connecting to an Access DB,  updating, inserting, and deleting rows.
References
[1]        How Do I Know if I’m Running 32-bit or 64-bit Office 2010?           
                Accessed 02/2013
[2]        Microsoft Access Database Engine 2010 Redistributable
                Accessed 02/2013

2 comments:

  1. there is also an article with demo app here

    http://geeksprogrammings.blogspot.com/2013/10/connect-access-database-with-c.html

    ReplyDelete
  2. Hi I'm using VS 2012 & Office 2013 64 bits, and i changed the target platform to x86, but I still got this weard error "The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine"..

    ReplyDelete