Ошибка говорит мне, что я не закрыл соединение, но не так ли?
Должно быть, я что-то здесь упустил. Я пытаюсь создать таблицу, но получаю сообщение об ошибке, сообщающее, что соединение все еще открыто. Но где??? Я перечитал код, но не могу найти, где еще открыто соединение...
Проблема лежит здесь: 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;