WPF - 如何以编程方式备份​​/恢复 LocalDB - ClickOnce

Posted

技术标签:

【中文标题】WPF - 如何以编程方式备份​​/恢复 LocalDB - ClickOnce【英文标题】:WPF - How to Backup / Restore LocalDB Programmatically - ClickOnce 【发布时间】:2014-11-15 23:52:32 【问题描述】:

我有一个使用 EF 和 LocalDB 作为数据库的应用程序,由 ClickOnce 发布。 这是我第一次使用 LocalDB,我不知道如何向我的应用程序添加功能以编程方式备份​​/恢复数据库。

ClickOnce 安装的我的应用路径:

C:\Users\Mahdi Rashidi\AppData\Local\Apps\2.0\NOL11TLW.9XG\CZM702AQ.LPP\basu..tion_939730333fb6fcc8_0001.0002_fd707bbb3c97f8d3

这是安装数据库文件的位置:

C:\Users\Mahdi Rashidi\AppData\Local\Apps\2.0\NOL11TLW.9XG\CZM702AQ.LPP\basu...exe_939730333fb6fcc8_0001.0002_none_8c555c3966727e7f
    我应该如何备份/恢复数据库? 如何确保数据库免受 ClickOnce 进一步更新的影响?

非常感谢:)

【问题讨论】:

如何将数据保存到C:\Users\[USER]\AppData\Roaming\[SOMEFOLDER],而不是数据库安装目录?这将回答#2。对于 #1:使用 board utils? 感谢@Herdo,我认为这不取决于保存目录,因为当我用新文件替换 .mdf 文件并运行应用程序时,它显示第一个 db 的内容而不是新的。我想知道是否有任何标准方法可以在应用程序运行时以编程方式备份​​和恢复数据库?! 顺便说一句,我找到了第二个问题的答案,唯一剩下的问题是第一个问题。 【参考方案1】:

这就是我为我的 localDb 备份和恢复所做的操作

public void BackupDatabase(string filePath)
    
        using (TVend2014Entities dbEntities = new TVend2014Entities(BaseData.ConnectionString))
        
            string backupQuery = @"BACKUP DATABASE ""0"" TO DISK = N'1'";
            backupQuery = string.Format(backupQuery, "full databsase file path like C:\tempDb.mdf", filePath);
            dbEntities.Database.SqlQuery<object>(backupQuery).ToList().FirstOrDefault();
        
    

    public void RestoreDatabase(string filePath)
    
        using (TVend2014Entities dbEntities = new TVend2014Entities(BaseData.ConnectionString))
        
            string restoreQuery = @"USE [Master]; 
                                                ALTER DATABASE ""0"" SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
                                                RESTORE DATABASE ""0"" FROM DISK='1' WITH REPLACE;
                                                ALTER DATABASE ""0"" SET MULTI_USER;";
            restoreQuery = string.Format(restoreQuery, "full db file path", filePath);
            var list = dbEntities.Database.SqlQuery<object>(restoreQuery).ToList();
            var resut = list.FirstOrDefault();
        
    

希望这是你想要的。

【讨论】:

感谢您完成该项目,我使用 ClosedXML 将数据备份到 Excel 文件中并从中恢复它们....,但您的代码似乎是执行备份/恢复工作的好方法.我应该使用它。 它非常适合我。优点是您可以在同一数据库上进行还原。非常感谢。【参考方案2】:

我曾经有过一段时间让我的备份/恢复工作从我的应用程序中的代码开始。我正在使用 LOCALDB 并希望确保无论数据库的状态或 .mdf 文件的位置如何,备份和还原功能都可以正常工作。毕竟 - DBMS 应该为您处理这些问题。最后,这就是我让备份和恢复功能发挥作用的方式: 注意:VB中的代码 - 保存“;” :)

备份:

 Dim cbdfilename As String = controlPath & "\Backup\Temp\cbdb.bak"
    Dim connString As String = (server + ";Initial Catalog=master;Integrated Security=True;")
    Dim conn As New SqlConnection(connString)
    Dim sql As String
    sql = "Backup database @DBNAME " _
    & " to Disk = @FILENAME" _
    & " with Format"
    SqlConnection.ClearAllPools()
    'execute backup
    Dim dbcmd As New SqlCommand(sql, conn)
    dbcmd.Parameters.AddWithValue("@DBNAME", database)
    dbcmd.Parameters.AddWithValue("@FILENAME", cbdfilename)
    conn.Open()
    Try
        dbcmd.ExecuteNonQuery()
    Catch ex As Exception
        MsgBox("Backup DB failed" + ex.ToString)
    Finally
        conn.Close()
        conn.Dispose()
    End Try

上面要注意的关键是 SqlConnection.ClearAllPools() 语句。即使我确定所有连接都已在我的应用程序的其他部分正确关闭和处理 - 不知何故,DBMS 仍然显示一个打开的线程。

现在是恢复:

SqlConnection.ClearAllPools()
        Dim connString As String = (server + ";Initial Catalog=master;Integrated Security=True;")
        Dim conn As New SqlConnection(connString)
        Dim sql As String
        sql = "Use master;" _
            & "Alter Database " & database & " Set Single_User With Rollback Immediate;" _
            & "Restore Database " & database & " From Disk = @FILENAME" _
            & " With Replace;" _
            & "Alter Database " & database & " Set Multi_User;"

        'execute restore
        Dim dbcmd As New SqlCommand(sql, conn)
        dbcmd.Parameters.AddWithValue("@FILENAME", cbdfilename)
        conn.Open()
        Try
            dbcmd.ExecuteNonQuery()
        Catch ex As Exception
            MsgBox("Restore DB failed" + ex.ToString)
        Finally
            conn.Close()
            conn.Dispose()
        End Try

上面的 SQL 中真正奇怪的是,我最初尝试使用 @Parms 作为数据库名称,但 ALTER 语句不接受它们。不断反击,有例外。

我的还原与早期解决方案的最大区别在于我只使用数据库名称,即。 “MyDB_TEST”而不是我的 Alter 和 Restore 语句中的 .mdf 文件名。

【讨论】:

以上是关于WPF - 如何以编程方式备份​​/恢复 LocalDB - ClickOnce的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式单击 WPF 中的按钮?

如何以编程方式将图像放入进度条(WPF)

WPF ListView - 如何以编程方式添加项目?

如何以编程方式导航 WPF UI 元素制表位?

如何以编程方式选择 WPF TreeView 中的项目?

如何以编程方式选择WPF TreeView中的项目?