如何分离数据库以便可以复制/移动它?

时间:2014-12-20 09:54:29

标签: c# sql-server wpf entity-framework-6 localdb

我使用Database first EF方法在使用C#的wpf应用程序中创建Model。添加相关信息后,更改列的名称,表格名称,我想将其复制到新位置。但是我收到数据库正在使用的错误消息。

using (var ctx = new TableGraphDBEntities())
{
    for (int l = 0, m = 1; l < TableNames.Count; l++, m++)
    {
        string columnxQ = "sp_rename 'Table1.x','" + XNames[l] + "', 'COLUMN'";
        string columnyQ = "sp_rename 'Table1.y','" + YNames[l] + "', 'COLUMN'";
        string talbeQ = "sp_rename Table" + m.ToString() + "," + TableNames[l];
        string detachQ = "sp_detach_db @dbname = N'TableGraphDB'";
        //string setOffline = "
        //string detachQ = "USE master; GO EXEC sp_detach_db @dbname = N'TableGraphDB'; GO";
        ctx.Database.ExecuteSqlCommand(columnxQ);
        ctx.Database.ExecuteSqlCommand(columnyQ);
        ctx.Database.ExecuteSqlCommand(talbeQ);
        ctx.Database.ExecuteSqlCommand(detachQ);


    }     
}
string oldFilePath = System.AppDomain.CurrentDomain.BaseDirectory + "TableGraphDB.mdf";
string FilePath = Properties.Settings.Default.ExtensionFileDir + @"\Saved DataBases\" + fnw.FileName + ".mdf";
if (File.Exists(FilePath))
{
    MessageBox.Show("The database aleady exist, please type a different name");
    return;
}
//FileInfo fileInfo = new FileInfo(oldFilePath);
//while (IsFileLocked(fileInfo))
//{

//}
File.Copy(oldFilePath, FilePath);
MessageBox.Show("Database is saved!");

以下是slq命令http://msdn.microsoft.com/en-gb/library/ms187858.aspx

的链接

数据库位于Bin文件夹中。每次运行应用程序时,它都会从项目中复制为新副本。如果我关闭应用程序并重新打开它,可以将其与所有数据一起复制。

我尝试过使用ExecuteSqlCommand(),但它没有帮助。 那么我怎么能分离数据库以便我可以移动/复制它?

不幸的是StackOverFlow不允许我回答我自己的问题,所以我必须在这里写下来。

答案: 首先,您必须检查数据库的实际名称,它不一定是数据库文件的名称。为此,您需要:

  1. 在Visual Studio或SQL Management Studio中打开服务器资源管理器。
  2. 打开新查询。
  3. 执行以下查询: SELECT name,create_date FROM sys.databases
  4. 检查数据库的名称(在我的例子中,它是数据库文件的完整路径,它只能是数据库的名称或其他任何内容。)
  5. 然后,您可以通过执行以下代码来更改列和表的名称:

    using (var ctx = new TableGraphDBEntities())
    {
        for (int l = 0, m = 1; l < TableNames.Count; l++, m++)
        {
            string columnxQ = "sp_rename 'Table1.x','" + XNames[l] + "', 'COLUMN'";
            string columnyQ = "sp_rename 'Table1.y','" + YNames[l] + "', 'COLUMN'";
            string talbeQ = "sp_rename Table" + m.ToString() + "," + TableNames[l];
            ctx.Database.ExecuteSqlCommand(columnxQ);
            ctx.Database.ExecuteSqlCommand(columnyQ);
            ctx.Database.ExecuteSqlCommand(talbeQ);
            ctx.Dispose();
        }
    }
    

    最后使用以下代码分离并将其移动到新位置:

    string oldFilePath = System.AppDomain.CurrentDomain.BaseDirectory + "TableGraphDB.mdf";
    string conString = @"Data Source=(LocalDB)\v11.0;Integrated Security=True;";
    using (System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(conString))
    {
        string query = @"USE [master] 
            ALTER DATABASE ["+oldFilePath+@"] SET  SINGLE_USER WITH ROLLBACK IMMEDIATE
            USE [master] 
            EXEC master.dbo.sp_detach_db @dbname = N'"+oldFilePath+"'";
        SqlCommand cmd = new SqlCommand(query, con);
        con.Open();
        cmd.ExecuteNonQuery();
        cmd.Dispose();
        con.Dispose();
    }
    
    string FilePath = Properties.Settings.Default.ExtensionFileDir + @"\Saved DataBases\" + fnw.FileName + ".mdf";
    if (File.Exists(FilePath))
    {
        MessageBox.Show("The database aleady exist, please type a different name");
        return;
    }
    File.Copy(oldFilePath, FilePath);
    

    注意:如果您尝试实施ctx.Database.ExecuteSqlCommand(查询),则会收到以下错误:

      

    多语句事务中不允许使用ALTER DATABASE语句。   程序&#39; sys.sp_detach_db&#39;无法在交易中执行。   将数据库上下文更改为&#39; master&#39;。

2 个答案:

答案 0 :(得分:1)

如果您正在使用EF6,可以尝试以下代码:

string command = "EXEC sp_detach_db 'TableGraphDB', 'true'";
dbContext.ExecuteStoreCommand(command);

sp_detach_db过程中的第二个参数将删除与此数据库的所有连接

答案 1 :(得分:1)

在SSMS中,这是用于分离数据库的查询。 你能试试吗?

你应该能够将整个事物包装成一个字符串并执行它。 我不确定它是否会对“GO&#39”感到满意,所以你可能不得不删除它们。

string detachQ = "" + 
"USE [master]\n" +
"GO\n" +
"ALTER DATABASE [TableGraphDB] SET  SINGLE_USER WITH ROLLBACK IMMEDIATE\n" +
"GO\n" +
"USE [master]\n" +
"GO\n" +
"EXEC master.dbo.sp_detach_db @dbname = N'TableGraphDB'\n" +
"GO\n";

ctx.Database.ExecuteSqlCommand(detachQ);