如何通过C#代码导出数据库并在本地导入?
如何通过C#应用程序将数据库从远程服务器“克隆”到LocalDB数据库?不需要与远程数据库建立关系 背景 应用程序是使用.NET 4.5.2以C#编写的,支持两种模式—联机连接到远程MS SQL Server数据库,脱机连接到如何通过C#代码导出数据库并在本地导入?,c#,sql-server,sqlbulkcopy,C#,Sql Server,Sqlbulkcopy,如何通过C#应用程序将数据库从远程服务器“克隆”到LocalDB数据库?不需要与远程数据库建立关系 背景 应用程序是使用.NET 4.5.2以C#编写的,支持两种模式—联机连接到远程MS SQL Server数据库,脱机连接到LocalDB数据库。该应用程序主要针对较新版本的服务器(如果有必要,只支持2014版是可以的) 在用户脱机之前,它应该要求应用程序将远程数据库克隆到LocalDB数据库(本地数据库被完全覆盖)。本地数据库应独立于远程数据库,即无从属数据库或复制数据库 联机和脱机连接字符串
LocalDB
数据库。该应用程序主要针对较新版本的服务器(如果有必要,只支持2014版是可以的)
在用户脱机之前,它应该要求应用程序将远程数据库克隆到LocalDB
数据库(本地数据库被完全覆盖)。本地数据库应独立于远程数据库,即无从属数据库或复制数据库
联机和脱机连接字符串都包含相应数据库的名称。应用程序本身不直接知道数据库名或表名,因为这是由连接字符串和实体框架管理的
问题
如何将远程数据库“克隆”到LocalDB
数据库(远程数据库名称和LocalDB
数据库名称可能不同)
我更喜欢不需要启动外部程序的解决方案,但这不是一个硬性要求
问题
通过实体框架复制没有跟踪实体是不可接受的慢
我知道备份数据库
和恢复数据库
命令,但我发现了以下困难:
RESTORE DATABASE
命令包含光盘上各个数据文件的名称和路径(MOVE
parts)。有没有一种方法可以在不提供数据文件路径的情况下只指定数据库名称来处理它?或者如何通过SQL命令获取数据文件路径(要获取文件名,我只需创建一个空白数据库,获取文件名,或者删除数据库并使用检索到的文件名)有更好的方法吗 我使用我创建的存储过程,但首先需要创建一个链接服务器:
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
我建议你去上一堂复印机课。它在你的标签里,但是你根本没有在文本中提到它。你试过了吗?谢谢,我不知道它实际上是一门课。感谢您的建议,我已经找到并使用了提供的
PerformBulkCopy
示例代码来构建实际代码。我建议使用SSIS包来获取最新数据。您可以使用它进行增量或完全刷新。很抱歉之前没有说明这一点。用户可以在脱机运行时进行(非常有限的)一组更改。当切换到在线时,应用程序会在在线数据上模拟这些变化。所以为了安全起见,我更喜欢完全重写离线数据库。Express edition中不包含SSI,因此它可能会使我们的生活更加困难(数据库服务器上的应用程序将产生非常小的流量,因此如果没有更好的部署,则Express edition是可以的)。截断表+在本地数据库中插入旧的学校将起作用。或是复印件。您最大的表中有多少条记录?