为什么我必须复制我的代码来处理两个同步的MSSQL数据库

本文关键字:两个 同步 数据库 MSSQL 处理 复制 我的 代码 为什么 | 更新日期: 2023-09-27 17:57:26

我正在编写一个与SQL服务器连接的应用程序。这个连接不是很稳定,所以我决定使用Microsoft Sync Framework,它非常好。我的问题是,我必须使用两倍多的数据集&tableadapter,另外,当我在本地数据库和服务器数据库之间切换时,我必须更改所有winform数据源(例如:combobox)。

我想要实现的是在两个数据库之间轻松切换。我有一个完整的工作代码,但我认为它可能会更好。

初始化代码:

int timeout = 5;
public Form1()
{
    Program.ChangeConnectionString("TESTDBConnectionString", "Data Source=ip''engine;Initial Catalog=TESTDB;Persist Security Info=True;User ID=usr;Password=psw; Connect Timeout = " + timeout);
    Program.ChangeConnectionString("localConnectionString", "Data Source = (LocalDB)''MSSQLLocalDB; AttachDbFilename = ''local.mdf; Integrated Security = True; Connect Timeout = " + timeout);
    InitializeComponent();
}

更新(和连接检查)代码:

private void UpdateDB()
{
    CheckServer();
    this.tbl_SyncTestTableAdapter1.Fill(this.localDataSet1.tbl_SyncTest);
    if (Program.IsOnline)
    {
        this.tbl_SyncTestTableAdapter.Fill(this.tESTDBDataSet.tbl_SyncTest);
        tblSyncTestBindingSource.DataSource = tESTDBDataSet.tbl_SyncTest;
        tblSyncTestBindingSource1.DataSource = tESTDBDataSet.tbl_SyncTest;
        tblSyncTestBindingSource2.DataSource = tESTDBDataSet.tbl_SyncTest;
        tblSyncTestBindingSource4.DataSource = tESTDBDataSet.tbl_SyncTest;
        dataGridView2.Visible = true;
        Sync();
    }
    else
    {
        tblSyncTestBindingSource.DataSource = localDataSet1.tbl_SyncTest;
        tblSyncTestBindingSource1.DataSource = localDataSet1.tbl_SyncTest;
        tblSyncTestBindingSource2.DataSource = localDataSet1.tbl_SyncTest;
        tblSyncTestBindingSource4.DataSource = localDataSet1.tbl_SyncTest;
        dataGridView2.Visible = false;
        label8.Text = "OFFLINE";
    }
}

示例数据库操作:

private void button3_Click(object sender, EventArgs e)
{
    string[] val = new string[] { comboBox2.Text, textBox5.Text, textBox4.Text };
    int ival = (int)comboBox2.SelectedValue;
    CheckServer();
    if (Program.IsOnline) tbl_SyncTestTableAdapter.Update(val[0], val[1], val[2], ival);
    else tbl_SyncTestTableAdapter1.Update(val[0], val[1], val[2], ival);
    UpdateDB();
}

如果你需要更多的代码,请告诉我,但我认为其他的都是不可抗拒的

编辑,同步代码:

private void Sync()
{
    label8.Text = "SYNCING...";
    new Task(() =>
    {
        ProvisionServer();
        ProvisionLocal();
        SqlConnection serverConn = new SqlConnection(Properties.Settings.Default["TESTDBConnectionString"].ToString());
        SqlConnection localConn = new SqlConnection(Properties.Settings.Default["localConnectionString"].ToString());
        SyncOrchestrator syncOrchestrator = new SyncOrchestrator();
        syncOrchestrator.LocalProvider = new SqlSyncProvider("TestScope", localConn);
        syncOrchestrator.RemoteProvider = new SqlSyncProvider("TestScope", serverConn);
        syncOrchestrator.Direction = SyncDirectionOrder.DownloadAndUpload;
        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);
        this.BeginInvoke((Action)(() =>
        {
            label8.Text = "SYNCED";
            this.tbl_SyncTestTableAdapter.Fill(this.tESTDBDataSet.tbl_SyncTest);
            this.tbl_SyncTestTableAdapter1.Fill(this.localDataSet1.tbl_SyncTest);
        }));
    }).Start();
}

为什么我必须复制我的代码来处理两个同步的MSSQL数据库

存在DataAdapter模式,因此您可以为不同的场景Adapt,而不必在整个应用程序中实现/复制相同的逻辑。在您的案例中,您只对选择正确的适配器实现感兴趣。

如果这是你唯一的表单,你可以引入一个获得合适DataAdapter的属性,并在整个过程中使用它。

// Adapter will give you an interface
// to either your local store
// or your online store
private IDataAdapter Adapter 
{
   get 
   {
       IDataAdapter _adapter = null;
       CheckServer();
       if (Program.IsOnline) 
       {
            _adapter = new SqlDataAdapter(selectcommand, onlineconnection);
       }
       else
       {
            _adapter = new  SqlCeDataAdapter(selectCommand, offlineConnection);
       }
       return _adapter
   }   
} 

您的其他方法只能处理单个数据集:

private void UpdateDB()
{
    this.Adapter.Fill(this.localDataSet1);
    // you don't need to change any bindings ...
}

你的数据库操作:

private void button3_Click(object sender, EventArgs e)
{
    string[] val = new string[] { comboBox2.Text, textBox5.Text, textBox4.Text };
    // if the Adapter has changed here
    // the dataset might hold different states
    // so it might hold on Update where an Insert is needed
    // in that case use some logic to Fill a new Dataset and merge that
    // with the current one
    this.Adapter.Update(this.localDataSet1); // the values from the dataset will be stored.
}

但是,既然您已经展示了同步代码,为什么不简单地始终连接到本地数据库,然后让同步框架处理本地和中央数据库中所需的更新/插入呢。在选择DataAdapter的情况下,将在线和离线场景的逻辑引入其中,首先会违背同步框架的目的。