2016-04-07 11 views
2

Veritabanında GUI aracılığıyla değişiklik yapan yazılım üzerinde çalışıyorum. Kullanıcı tıklamaları kaydettikten sonra veritabanını sıkıştırmak istiyorum. Kullanıcı kaydettikten sonra yazılımı kullanmaya devam edebilir veya kapatıp "kullanıyorum". OleDbConnection bağlantı nesnesini birkaç tane ile birlikte tutan databaseAccess nesnesini oluşturdum. Bu benim veritabanı erişim sınıfım. "Dbe.CompactDatabase (accessFile, tempfile);"dosya zaten dispose ve SuppressFinalize kullanıldıktan sonra kullanım istisnası MS access File

using System; 
using System.Collections.Generic; 
using System.Data.OleDb; 
using System.Data; 
using System.Diagnostics; 
using System.Windows.Forms; 

namespace TreeTool 
{ 
    public class DataBaseAccess 
    { 
     #region Properties 
     private string m_directory; 
     public List<string> selectedTableNames; 
     private Dictionary<String, DataTable> selectedTables; 
     private OleDbConnection mdbConnection; 
     DataTable dataTable; 

     //Constructor 
     public DataBaseAccess() 
     { 
      selectedTableNames = new List<string>(); 
      selectedTables = new Dictionary<string, DataTable>(); 
     } 

     public string directory 
     { 
      get 
      { 
       return m_directory; 
      } 
      set 
      { 
       m_directory = value; 
      } 
     } 
     #endregion 
     public List<string> GetAllTableNames() 
     { 
      if (dataTable != null) 
      { 
       List<string> tableList = new List<string>(); 
       for (int i = 0; i < dataTable.Rows.Count; i++) 
       { 
        string TableName = dataTable.Rows[i][2].ToString(); 
        tableList.Add(TableName); 
       } 
       return tableList; 
      } 
      return null; 
     } 

     /// <summary> 
     /// Returns Table Columns 
     /// </summary> 
     /// <returns></returns> 
     public DataTable GetTable(string TableName) 
     { 
      DataTable mdbTable; 
      if (selectedTables.TryGetValue(TableName, out mdbTable)) 
      { 
       return mdbTable; 
      } 
      else 
      { 
       mdbTable = new DataTable(); 
       //mdbConnection.Open(); 
       string mdbCommandString = "SELECT * FROM [" + TableName + "]"; 
       OleDbDataAdapter QueryCommand = new OleDbDataAdapter(mdbCommandString, mdbConnection); 
       QueryCommand.Fill(mdbTable); 
       //mdbConnection.Close(); 

       selectedTables.Add(TableName, mdbTable); 

       return mdbTable; 
      } 
     } 

     public void SetTable(String TableName, DataTable dataTable) 
     { 
      //mdbConnection.Open(); 

      OleDbCommand ac = new OleDbCommand("delete from [" + TableName + "]", mdbConnection); 
      ac.ExecuteNonQuery(); 

      foreach (DataRow row in dataTable.Rows) 
      { 
       String query = "INSERT INTO [" + TableName + "] (TaskID, HTMLTopic, nRelative, [Group], nKey," 
        + " [nText], nImage, nSelImage, nFontName, nFontInfo, Keywords) VALUES (@TaskID," 
        + " @HTMLTopic, @nRelative, @Group, @nKey, @nText, @nImage, @nSelImage, @nFontName, " 
        + " @nFontInfo, @Keywords)"; 
       OleDbCommand command = new OleDbCommand(query, mdbConnection); 
       command.Parameters.AddWithValue("@TaskID", row["TaskID"]); 
       command.Parameters.AddWithValue("@HTMLTopic", row["HTMLTopic"]); 
       command.Parameters.AddWithValue("@nRelative", row["nRelative"]); 
       command.Parameters.AddWithValue("@Group", row["Group"]); 
       command.Parameters.AddWithValue("@nKey", row["nKey"]); 
       command.Parameters.AddWithValue("@nText", row["nText"]); 
       command.Parameters.AddWithValue("@nImage", row["nImage"]); 
       command.Parameters.AddWithValue("@nSelImage", row["nSelImage"]); 
       command.Parameters.AddWithValue("@nFontName", row["nFontName"]); 
       command.Parameters.AddWithValue("@nFontInfo", row["nFontInfo"]); 
       command.Parameters.AddWithValue("@Keywords", row["Keywords"]); 
       command.ExecuteNonQuery(); 
      } 

      //mdbConnection.Close(); 
     } 

     internal bool validTable(string TableName) 
     { 
      DataTable mdbTable = new DataTable(); 

      //mdbConnection.Open(); 

      string mdbCommandString = "SELECT * FROM [" + TableName + "]"; 
      OleDbDataAdapter QueryCommand = new OleDbDataAdapter(mdbCommandString, mdbConnection); 
      QueryCommand.Fill(mdbTable); 
      //mdbConnection.Close(); 

      // check if table contains all columns necessary 
      String[] columnNames = new string[] { "TaskID" , "HTMLTopic", "nRelative", "Group", "nKey", 
       "nText", "nImage", "nSelImage", "nFontName", "nFontInfo", "Keywords"}; 

      Boolean missingColumn = false; 

      DataColumnCollection columns = mdbTable.Columns; 
      foreach (String columnName in columnNames) 
      { 
       if (columns.Contains(columnName) == false) 
       { 
        // print the message 
        MessageBox.Show("Database: " + directory + " Table: " + TableName + " is missing column \"" + columnName 
         + "\". Add it to make changes.", 
         "Missing column", 
         MessageBoxButtons.OK, 
         MessageBoxIcon.Exclamation, 
         MessageBoxDefaultButton.Button1); 
        missingColumn = true; 
       } 
      } 

      if (missingColumn == true) 
      { 
       return false; 
      } 
      return true; 
     } 

     public void insertTable(String tableName) 
     { 
      selectedTableNames.Add(tableName); 
     } 

     public List<String> getSelectedTables() 
     { 
      return selectedTableNames; 
     } 

     public Boolean isConnected() 
     { 
      if (mdbConnection == null) 
      { 
       return false; 
      } 
      return true; 
     } 

     public void connect() 
     { 
      if (mdbConnection == null) 
      { 
       String m_mdbDirectory = @"Provider=Microsoft.JET.OLEDB.4.0;Data Source=" + m_directory; 
       mdbConnection = new OleDbConnection(m_mdbDirectory); 
       mdbConnection.Open(); 
       string[] restrictions = new string[4]; 
       restrictions[3] = "Table"; 
       dataTable = mdbConnection.GetSchema("TABLES", restrictions); 
       //mdbConnection.Close(); 
      } 
     } 

     public void disconnect() 
     { 
      mdbConnection.Close(); 
      mdbConnection.Dispose(); 
      GC.SuppressFinalize(mdbConnection); 
      mdbConnection = null; 
     } 

     public void clearSelectedTables() 
     { 
      selectedTableNames.Clear(); 
     } 
    } 
} 

Kaydet ve kompakt fonksiyonları istisna hattında meydana bu

private void save() 
    { 
     foreach(DataBaseAccess database in databases) 
     { 
      // save changes code 
      database.disconnect(); 
      CompactAndRepairAccessDB(database.directory); 
      database.connect(); 
     } 
    } 

    private void CompactAndRepairAccessDB(string accessFile) 
    { 
     string tempFile = @"temp.mdb"; 
     FileInfo temp = new FileInfo(tempFile); 

     // Required COM reference for project: 
     // Microsoft Office 14.0 Access Database Engine Object Library 
     var dbe = new Microsoft.Office.Interop.Access.Dao.DBEngine(); 
     try 
     { 
      dbe.CompactDatabase(accessFile, tempFile); 
      temp.CopyTo(accessFile, true); 
      temp.Delete(); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("Error: " + e.Message); 
     } 
    } 

gibidir.

+0

Kodun hangi kısmında hata oluşur? – Smartis

+0

dbe.CompactDatabase (accessFile, tempFile); – Ruturaj

+0

Neden "GC.SuppressFinalize" kullanıyorsunuz? Neden Finalizer'ın çağrılmamasını istiyorsunuz? – Camo

cevap

1

OleDbDataAdapter ve OleDbCommand'u kullandığınız tüm yöntemlerde bulunan kodda, bu nesneler üzerinde Use-Pattern kullandığınızdan emin olun. Gerçek bağlantı zaten bertaraf edilmiş olsa bile mdb dosyasını açık tutabilirler. Değişiklik gerektiren yöntemler GetTable, SetTable ve ValidTable gibi görünüyor.

+0

çalıştı. Teşekkür ederim. – Ruturaj