2014-11-27 3 views
3

Как «клонировать» базу данных с удаленного сервера в базу данных LocalDB с помощью приложения C#? Никаких связей с удаленной базой данных не требуется.Как экспортировать базу данных и импортировать ее локально с помощью кода на C#?

фон

Применение написано на C# с использованием .NET 4.5.2 и поддерживает два режима - онлайн, который подключается к удаленной базе данных MS SQL Server, и в автономном режиме, который подключается к базе данных LocalDB. Приложение в первую очередь нацелено на более новые версии серверов (если это имеет значение, поддержка только версии 2014 в порядке).

Перед тем, как пользователь перейдет в автономный режим, он должен попросить приложение клонировать удаленную базу данных в базу данных LocalDB (локальная база данных полностью перезаписана). Локальная база данных должна быть независимой от удаленной базы данных, то есть без ведомого или репликации.

Как сетевая, так и автономная строка подключения содержит имя соответствующей базы данных. Само приложение не имеет прямого знания имени базы данных или имен таблиц, так как это управляется строками соединения и структурой Entity Framework.

Вопрос

Как «клон» удаленной базы данных в базу данных LocalDB (имя удаленной базы данных и имя LocalDB базы данных может отличаться)?

Я предпочитаю решение, которое не требует запуска внешней программы, но это не является жестким требованием.

Вопросы

Копирование через Entity Framework нет отслеживания лиц неприемлемо медленно.

Я знаю команды BACKUP DATABASE и RESTORE DATABASE, но я нашел следующие трудности:

  1. Они требуют от меня, чтобы указать имя базы данных. Есть ли способ, как по умолчанию использовать исходную базу данных, указанную как часть строки подключения?

  2. Команда RESTORE DATABASE содержит имена и пути соответствующих файлов данных на диске (MOVE частей). Есть ли способ обработать его с указанием имени базы данных без указания пути к файлам данных? Или как получить пути к файлам данных с помощью команд SQL (чтобы получить имена файлов, я просто создаю пустую базу данных, получаю имена файлов, необязательно удаляю базу данных и использую имена файлов, которые вы получили)?

Есть ли лучший способ сделать это?

+2

Я бы предложил класс SqlBulkCopy. Это в ваших тегах, но вы вообще не упоминаете об этом в тексте. Вы попробовали это? – TomT

+0

Спасибо, я не знал его на самом деле класс. Благодаря вашему предложению я нашел http://www.codeproject.com/Articles/18418/Transferring-Data-Using-SqlBulkCopy и использовал предоставленный код примера «PerformBulkCopy» для создания фактического кода. – alik

+0

Я предлагаю использовать пакеты SSIS для получения последних данных. Вы можете сделать инкрементное или полное обновление, используя это. – Raghuveer

ответ

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' 

Затем вы можете создать хранимую процедуру на локальном сервере или выполнить запрос непосредственно из приложения, а также для безопасности I я использую транзакцию в этом примере:

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 

 Смежные вопросы

  • Нет связанных вопросов^_^