从本地 SQL 服务器数据库和 C# 同步实时数据库
Synchronize live database from local SQL Server database & C#
我正在使用 C# 中的 Entity Framework 开发 ASP.NET MVC 应用程序。我有一种情况,我必须制作两个具有相同模式的数据库。一次一台 PC 正在使用该应用程序并更新 PC 上的本地数据库。
现在我希望该本地数据库更新放置在我的远程(实时)服务器上的另一个数据库。该更新将在触发后发生(我不希望它在特定时间间隔后自动同步或同步)。
我在互联网上搜索并找到了 this one 以及其他一些解决方案。
大多数人都在使用复制管理对象 (RMO)。我需要了解一些事情:
- 是否有任何其他同步数据库的简单方法,或者我应该使用 RMO?
- 我可以将 RMO 用于我的远程(实时)服务器吗?
- 服务器使用 RMO 的最低要求是什么?
- 在我的场景中,我应该创建推送订阅吗?
您可以搜索.NET Sync Framework
使用此框架,您可以创建 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 Class 将负责所有同步过程,它是 Microsoft Sync Frameworkclass
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();
}
如果发生任何更改或错误,此方法将 return。
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();
}
希望这对您有所帮助,我在一个项目中使用了这段代码,它对我来说效果很好。这仅适用于单个客户端和单机同步过程,不适用于多个。
我正在使用 C# 中的 Entity Framework 开发 ASP.NET MVC 应用程序。我有一种情况,我必须制作两个具有相同模式的数据库。一次一台 PC 正在使用该应用程序并更新 PC 上的本地数据库。
现在我希望该本地数据库更新放置在我的远程(实时)服务器上的另一个数据库。该更新将在触发后发生(我不希望它在特定时间间隔后自动同步或同步)。
我在互联网上搜索并找到了 this one 以及其他一些解决方案。
大多数人都在使用复制管理对象 (RMO)。我需要了解一些事情:
- 是否有任何其他同步数据库的简单方法,或者我应该使用 RMO?
- 我可以将 RMO 用于我的远程(实时)服务器吗?
- 服务器使用 RMO 的最低要求是什么?
- 在我的场景中,我应该创建推送订阅吗?
您可以搜索.NET Sync Framework 使用此框架,您可以创建 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 Class 将负责所有同步过程,它是 Microsoft Sync Frameworkclass
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();
}
如果发生任何更改或错误,此方法将 return。
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();
}
希望这对您有所帮助,我在一个项目中使用了这段代码,它对我来说效果很好。这仅适用于单个客户端和单机同步过程,不适用于多个。