如何导出数据库并通过C#代码在本地导入?

时间:2014-11-27 18:13:42

标签: c# sql-server sqlbulkcopy

如何克隆" C#应用程序从远程服务器到LocalDB数据库的数据库?不需要回到远程数据库的关系。

背景

应用程序使用.NET 4.5.2在C#中编写,并支持两种模式 - 在线连接到远程MS SQL Server数据库,以及脱机连接到LocalDB数据库。该应用程序主要针对较新版本的服务器(如果重要,只支持版本2014即可)。

在用户离线之前,应该要求应用程序将远程数据库克隆到LocalDB数据库(本地数据库被完全覆盖)。本地数据库应该独立于远程数据库,即没有从属或复制。

联机和脱机连接字符串都包含相应数据库的名称。应用程序本身并不直接了解数据库名称和表名,因为它由连接字符串和实体框架管理。

问题

如何克隆"远程数据库到LocalDB数据库(远程数据库名称和LocalDB数据库名称可能不同)?

我更喜欢不需要启动外部程序的解决方案,但这不是一项艰难的要求。

问题

通过实体框架进行复制,没有跟踪实体是不可接受的。

我知道BACKUP DATABASERESTORE DATABASE命令,但我发现了以下困难:

  1. 他们要求我指定数据库的名称。有没有办法将它们默认为指定为连接字符串一部分的初始数据库?

  2. RESTORE DATABASE命令包含光盘上各个数据文件的名称和路径(MOVE部分)。有没有办法如何在不提供数据文件路径的情况下仅指定数据库名称来处理它?或者如何通过SQL命令获取数据文件路径(为了获取文件名,我将创建一个空白数据库,获取文件名,可选择删除数据库并使用检索到的文件名)?

  3. 这样做有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

我使用我创建的存储过程,但首先需要创建链接服务器:

IF EXISTS(SELECT name FROM sys.servers WHERE name = 'SERVER')
            BEGIN-- 
                EXEC sp_dropserver 'SERVER', 'droplogins'
            END

/****** Object:  LinkedServer [SERVER]  create  LinkedServer ******/
            EXEC master.dbo.sp_addlinkedserver 
            @server = N'SERVER', 
            @srvproduct=N'SQLNCLI', 
            @provider=N'SQLNCLI', 
            @datasrc=N'192.168.1.1' -- IP address of a server   

             /* Add login data*/
            EXEC sp_addlinkedsrvlogin
            @useself='FALSE',
            @rmtsrvname='SERVER',
            @rmtuser='User',
            @rmtpassword='Pass'

然后你可以在本地服务器上创建存储过程或直接从应用程序执行查询,为了安全起见我在这个例子中使用了一个事务:

USE [DB]
GO
/****** Object:  StoredProcedure [dbo].[backupdatabase] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[backupdatabase]  
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    BEGIN TRY
        BEGIN TRANSACTION           
            TRUNCATE TABLE [dbo].[table_1]
            INSERT INTO [dbo].[table_1]
            SELECT * FROM [SERVER].[DB].[dbo].[table_1] 


            TRUNCATE TABLE [dbo].[table_2]
            INSERT INTO [dbo].[table_2]
            SELECT * FROM [SERVER].[DB].[dbo].[table_2] 


            TRUNCATE TABLE [dbo].[table_3]
            INSERT INTO [dbo].[table_3]
            SELECT * FROM [SERVER].[DB].[dbo].[table_3]             
        COMMIT      
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0
        BEGIN
            ROLLBACK TRANSACTION
            DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int
            SELECT @ErrMsg = ERROR_MESSAGE(),
            @ErrSeverity = ERROR_SEVERITY()
            RAISERROR(@ErrMsg, @ErrSeverity, 1)
        END         
    END CATCH
END