Ошибка говорит мне, что я не закрыл соединение, но не так ли?

Должно быть, я что-то здесь упустил. Я пытаюсь создать таблицу, но получаю сообщение об ошибке, сообщающее, что соединение все еще открыто. Но где??? Я перечитал код, но не могу найти, где еще открыто соединение...

Проблема лежит здесь: objOleDbConnection.Open()

Ошибка сказать:

You attempted to open a database that is already opened by user 'Admin' on machine 'machine'. Try again when the database is available.

private void sfdNewFile_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
{
    // Creating a ADOX object needed to create
    // new MS Access file.
    ADOX.Catalog createMSFile = new ADOX.Catalog();
    // Creating an object for a table.
    Table nTable = new Table();

    // Creating an object allowing me connecting to the database.
    OleDbConnection objOleDbConnection = new OleDbConnection();
    objOleDbConnection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" +
            "Data Source=" + sfdNewFile.FileName + ";Persist Security Info=False;Mode=12";
    // Creating command object.
    OleDbCommand objOleDbCommand = new OleDbCommand();
    objOleDbCommand.Connection = objOleDbConnection;

    try
    {
        // Created a new MS Access 2007 file with specified path.
        createMSFile.Create("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
            sfdNewFile.FileName);

        objOleDbConnection.Open();
        objOleDbCommand.CommandText = "CREATE TABLE PersonalData (" +
            "[DataID] AUTOINCREMENT NOT NULL PRIMARY KEY ," +
            "[Type] VARCHAR(40) NOT NULL ," +
            "[URL] VARCHAR(40) NOT NULL ," +
            "[SoftwareName] VARCHAR(40) NOT NULL ," +
            "[SerialCode] VARCHAR(40) NOT NULL ," +
            "[UserName] VARCHAR(40) NOT NULL ," +
            "[Password] VARCHAR(40) NOT NULL";

        objOleDbCommand.ExecuteNonQuery();
    }
    catch (Exception ex)
    {
        // Displaying any errors that 
        // might have occured.
        MessageBox.Show("Error: " + ex.Message);
    }
    finally
    {
        // It is importnat to release COM object, in this very order
        // otherwise we eill end up with an error.
        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(createMSFile);

        // Closing the connection to the database.
        objOleDbConnection.Close();
    }
}

4 ответа

Решение

Кажется, что объект ADOX должен также закрыть свое соединение. Посмотрите на следующий пример от Microsoft: http://msdn.microsoft.com/en-us/library/windows/desktop/ms681562(v=vs.85).aspx

Их объект ADOX называется cat. У них есть следующее:

cat.ActiveConnection = Nothing

Который, вероятно, будет переводить на:

createMSFile.ActiveConnection = null

В вашем коде (вероятно, в первом блоке "Наконец"). Я думаю, что это объект ADOX, который имеет значение, прежде чем избавиться от него, попробуйте установить его ActiveConnection на ноль.

Я должен признать, что я думал, что ADO действительно для C++ и VB, а не технологий.NET.

Цитировать отсюда

Внимание ADO и ADO MD не были полностью протестированы в среде Microsoft .NET Framework. Они могут вызывать периодические проблемы, особенно в сервисных приложениях или в многопоточных приложениях. Методы, которые обсуждаются в этой статье, должны использоваться только в качестве временной меры при переходе на ADO.NET. Вы должны использовать эти методы только после полного тестирования, чтобы убедиться в отсутствии проблем совместимости. Любые проблемы, вызванные использованием ADO или ADO MD таким способом, не поддерживаются. Дополнительные сведения см. В следующей статье базы знаний Майкрософт: 840667 При использовании ADO и ADO MD в приложении.NET Framework возникают непредвиденные ошибки.

На этой же странице вы увидите следующий код:

using System;
using ADOX;

namespace ConsoleApplication1
{
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            ADOX.CatalogClass cat = new ADOX.CatalogClass();

            cat.Create("Provider=Microsoft.Jet.OLEDB.4.0;" +
                   "Data Source=D:\\AccessDB\\NewMDB.mdb;" +
                   "Jet OLEDB:Engine Type=5");

            Console.WriteLine("Database Created Successfully");

            cat = null;

        }
    }
}

Я отмечаю, что вы не используете объект ADOX для каких-либо действий и вместо этого пытаетесь использовать OleDBCommands. Если вы собираетесь использовать ADOX, то вам следует создать таблицу с использованием объекта ADOX.

Вы должны открывать соединение, только если оно еще не открыто. Попробуй это:

if (objOleDbConnection.State != ConnectionState.Open)
{
    objOleDbConnection.Open()
}

Я не знаю, подходит ли вам это (никогда не использовал ADOX), но: http://www.pcreview.co.uk/forums/closing-access-file-created-adox-catalogclass-t1384766.html

tldr:

Marshal.ReleaseComObject(cat);
cat = null;
Другие вопросы по тегам