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

时间:2016-07-16 08:50:19

标签: c# sql-server winforms .net-4.0 microsoft-sync-framework

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

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

初始化代码:

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();
}

1 个答案:

答案 0 :(得分:1)

存在NA模式,因此您可以DataAdapter针对不同的方案,而无需在整个应用中实施/复制相同的逻辑。在您的情况下,您只对选择正确的Adapter实现感兴趣。

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

Adapt

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

// 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 ...
}

但是现在您已经透露了同步代码,为什么不是总是连接到本地数据库,然后让同步框架处理本地和本地所需的更新/插入在中央数据库。为在线和离线场景提供逻辑,您选择DataAdapter的方式首先会破坏同步框架的目的。