从本地SQL Server数据库和C#同步实时数据库

时间:2018-11-04 20:46:36

标签: c# sql-server entity-framework replication rmo

我正在使用C#中的实体框架开发ASP.NET MVC应用程序。在这种情况下,我必须使用相同的架构创建两个数据库,一次使用一台PC来使用该应用程序,并更新PC上的本地数据库。

现在,我希望本地数据库更新放置在远程(活动)服务器上的另一个数据库。该更新将在触发后发生(我不希望它自动同​​步,也不要在特定时间间隔后)。

我在互联网上进行搜索,发现了以下解决方案: https://code.msdn.microsoft.com/windowsdesktop/SQL-Server-Express-05c73322 以及其他一些。

大多数人都在使用复制管理对象(RMO)。我需要了解几件事:

  1. 是否还有其他简单的同步数据库的方法,还是应该使用RMO?
  2. 我可以将RMO用于远程(活动)服务器吗?
  3. 使用RMO的服务器的最低要求是什么?
  4. 在我的情况下,我应该创建推送订阅吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

您可以搜索.NET Sync Framework 使用此框架,您可以创建3种方法, 1.用于服务器计算机或目标计算机 2.用于客户端计算机或源计算机数据库 3.同步方法

首先根据您的选择为客户端和服务器以及作用域名称创建连接字符串。

 static string sServerConnection = @"Data Source=192.168.1.112;Initial Catalog=Server;User ID=sa;Password=123456";

    static string sClientConnection = @"Data Source=MAHAVEER;Initial Catalog=Client;Integrated Security=True";

    static string sScope = "MainScope";

从客户端计算机获取并存储数据

 //Get Data From Client Provision
    public static void ProvisionClient()
    {
        SqlConnection serverConn = new SqlConnection(sServerConnection);
        SqlConnection clientConn = new SqlConnection(sClientConnection);

        //Drop scope_Info Table
        string cmdText = @"IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES 
                   WHERE TABLE_NAME='scope_info') DROP table scope_info";
        clientConn.Open();
        SqlCommand cmd = new SqlCommand(cmdText, clientConn);
        cmd.ExecuteScalar();
        clientConn.Close();


        List<string> tables = new List<string>();
        tables.Add("Demo"); // Add Tables in List
        tables.Add("Product");

        var scopeDesc = new DbSyncScopeDescription("MainScope");
        foreach (var tbl in tables) //Add Tables in Scope
        {
            scopeDesc.Tables.Add(SqlSyncDescriptionBuilder.GetDescriptionForTable(tbl, clientConn));
        }

        SqlSyncScopeProvisioning clientProvision = new SqlSyncScopeProvisioning(clientConn, scopeDesc); //Provisioning

        //skip creating the user tables
        clientProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);

        //skip creating the change tracking tables
        clientProvision.SetCreateTrackingTableDefault(DbSyncCreationOption.Skip);

        //skip creating the change tracking triggers
        clientProvision.SetCreateTriggersDefault(DbSyncCreationOption.Skip);

        //skip creating the insert/update/delete/selectrow SPs including those for metadata
        clientProvision.SetCreateProceduresDefault(DbSyncCreationOption.Skip);

        //create new SelectChanges SPs for selecting changes for the new scope
        //the new SelectChanges SPs will have a guid suffix
        clientProvision.SetCreateProceduresForAdditionalScopeDefault(DbSyncCreationOption.Create);


        clientProvision.Apply();
    }

借助配置将数据设置到服务器计算机

    //Set Data To Server Provision
    public static void ProvisionServer()
    {

        SqlConnection serverConn = new SqlConnection(sServerConnection);

        string cmdText = @"IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES 
                   WHERE TABLE_NAME='scope_info') DROP table scope_info";
        serverConn.Open();
        SqlCommand cmd = new SqlCommand(cmdText, serverConn);
        cmd.ExecuteScalar();
        serverConn.Close();

        List<string> tables = new List<string>();
        tables.Add("Demo");
        tables.Add("Product");

        var scopeDesc = new DbSyncScopeDescription("MainScope");
        foreach (var tbl in tables)
        {
            scopeDesc.Tables.Add(SqlSyncDescriptionBuilder.GetDescriptionForTable(tbl, serverConn));
        }

        SqlSyncScopeProvisioning serverProvision = new SqlSyncScopeProvisioning(serverConn, scopeDesc); // Create Provision From All Tables

        //skip creating the user tables
        serverProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);

        //skip creating the change tracking tables
        serverProvision.SetCreateTrackingTableDefault(DbSyncCreationOption.Skip);

        //skip creating the change tracking triggers
        serverProvision.SetCreateTriggersDefault(DbSyncCreationOption.Skip);

        //skip creating the insert/update/delete/selectrow SPs including those for metadata
        serverProvision.SetCreateProceduresDefault(DbSyncCreationOption.Skip);

        serverProvision.Apply();


    }

上述两个过程之后,将根据您的要求开始同步过程,并且SyncOrchestrator类将负责所有同步过程,这是Microsoft Sync Framework的类

 public static void Sync()

    {
        SqlConnection serverConn = new SqlConnection(sServerConnection);

        SqlConnection clientConn = new SqlConnection(sClientConnection);

        SyncOrchestrator syncOrchestrator = new SyncOrchestrator();

        syncOrchestrator.LocalProvider = new SqlSyncProvider(sScope, clientConn);

        syncOrchestrator.RemoteProvider = new SqlSyncProvider(sScope, serverConn);

        syncOrchestrator.Direction = SyncDirectionOrder.Upload;

        ((SqlSyncProvider)syncOrchestrator.LocalProvider).ApplyChangeFailed += new EventHandler<DbApplyChangeFailedEventArgs>(Program_ApplyChangeFailed);

        SyncOperationStatistics syncStats = syncOrchestrator.Synchronize();

        Console.WriteLine("Start Time: " + syncStats.SyncStartTime);

        Console.WriteLine("Total Changes Uploaded: " + syncStats.UploadChangesTotal);

        //Console.WriteLine("Total Changes Downloaded: " + syncStats.DownloadChangesTotal);

        Console.WriteLine("Complete Time: " + syncStats.SyncEndTime);

        Console.WriteLine(String.Empty);

        Console.ReadLine();

    }

如果发生任何更改或错误,则此方法将返回。

    static void Program_ApplyChangeFailed(object sender, DbApplyChangeFailedEventArgs e)

    {

        Console.WriteLine(e.Conflict.Type);

        Console.WriteLine(e.Error);

    }

然后在main方法中调用以上三个方法。确保您必须以适当的方式调用这些方法,例如首先从客户端计算机接收到的数据比设置为服务器计算机的数据多,然后同步过程将开始

static void Main(string[] args)
    {
        ProvisionClient();
        ProvisionServer();
        Sync();
    }

我希望这对您有所帮助,我在一个项目中使用了此代码,对我来说很好。这仅适用于单个客户端和单个计算机同步过程,而不适用于多个客户端。