问题描述
我在我的应用程序中使用本地数据库,当我生成安装文件(通过 Installer Package)时,安装程序后它会出现数据库路径错误。
示例
an attempt to attach an auto-named database for file....
//OR
The given path format is not supported
我尝试编辑 app.config
文件中的数据库路径,但每次都失败,默认情况下我的代码行是这样的:
<add name="SampleDatabaseWalkthrough.Properties.Settings.SampleDatabaseConnectionString"
connectionString="Data Source=(LocalDB)\MSsqlLocalDB;AttachDbFilename=|DataDirectory|\SampleDatabase.mdf;Integrated Security=True"
providerName="System.Data.sqlClient" />
我的应用安装在 C:\Program Files (86)\App_Folder\Setup
请注意,未来的用户可能会在自定义路径中安装它,因此我需要一种方法来获取已安装应用的动态路径。
我的问题是如何获取应用安装路径以替换此部分 AttachDbFilename=|DataDirectory|\SampleDatabase.mdf
?
解决方法
您可以尝试使用 AppDomain.CurrentDomain.SetData
方法更改您的 mdf 文件路径。
因为,我不知道你是如何发布 winform 项目的。
我建议您使用 Clickonce 发布它。
首先,请将您的 mdf 文件包含在您的项目中。
第二,你可以试试下面的代码,在你发布之后更改安装路径。
private void Form1_Load(object sender,EventArgs e)
{
if(System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
{
string path = ApplicationDeployment.CurrentDeployment.DataDirectory; //Get installed path
AppDomain.CurrentDomain.SetData("DataDirectory",path);//set the DataDirectory
}
}
最后,根据我的测试,我可以在发布并安装到另一台计算机后从mdf文件中获取信息。
,在生产模式下,|DataDirectory|
指的是“bin”目录,而不是“app_data”。如果您将 .mdf
文件放在 app_data
目录中,您可以像这样更改它:
|DataDirectory|\SampleDatabase.mdf
到 |DataDirectory|\app_data\SampleDatabase.mdf
<add name="SampleDatabaseWalkthrough.Properties.Settings.SampleDatabaseConnectionString"
connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\app_data\SampleDatabase.mdf;Integrated Security=True"
providerName="System.Data.SqlClient" />
更新 1:
我正在发送一些代码。我只是想给你一个想法。您可以根据自己的情况进行更改。
private void Form1_Load(object sender,EventArgs e)
{
if (!IsExist())
{
CreateDatabase();
CreateTables();
}
}
// Create the Database
private void CreateDatabase()
{
string basePath = Environment.CurrentDirectory;
string mdfFile = "TestDatabase.mdf";
string ldfFile = "TestDatabase_Log.mdf";
string mdfFullPath = System.IO.Path.Combine(basePath,"Data",mdfFile);
string ldfFullPath = System.IO.Path.Combine(basePath,ldfFile);
SqlConnection myConn = new SqlConnection("Server=.;Data Source=(LocalDB)\\MSSQLLocalDB;Integrated security=SSPI;database=master");
string str = "CREATE DATABASE TestDatabase ON PRIMARY " +
"(NAME = TestDatabase," +
$"FILENAME = '{mdfFullPath}'," +
"SIZE = 2MB,MAXSIZE = 10MB,FILEGROWTH = 10%)" +
"LOG ON (NAME = MyDatabase_Log," +
$"FILENAME = '{ldfFullPath}'," +
"SIZE = 1MB," +
"MAXSIZE = 5MB," +
"FILEGROWTH = 10%)";
SqlCommand myCommand = new SqlCommand(str,myConn);
try
{
myConn.Open();
myCommand.ExecuteNonQuery();
MessageBox.Show("DataBase is Created Successfully","MyProgram",MessageBoxButtons.OK,MessageBoxIcon.Information);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString(),MessageBoxIcon.Information);
}
finally
{
if (myConn.State == ConnectionState.Open)
{
myConn.Close();
}
}
}
// Create the tables and other stuff that you want
private void CreateTables()
{
string conStr = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data\TestDatabase.mdf;Integrated Security=True;Connect Timeout=30";
SqlConnection myConn = new SqlConnection(conStr);
string str = @"CREATE TABLE [dbo].[TestTable]
(
[Id] INT NOT NULL PRIMARY KEY,[Test] NVARCHAR(50) NULL
)";
SqlCommand myCommand = new SqlCommand(str,myConn);
try
{
myConn.Open();
myCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(),MessageBoxIcon.Information);
}
finally
{
if (myConn.State == ConnectionState.Open)
{
myConn.Close();
}
}
}
// Check if there is the database
private bool IsExist()
{
string basePath = Environment.CurrentDirectory;
string mdfFile = "TestDatabase.mdf";
string mdfFullPath = System.IO.Path.Combine(basePath,mdfFile);
return System.IO.File.Exists(mdfFullPath);
}