服務器上保存有上萬條的基礎數據,須要同步到全國各地的成千上萬個客戶端,並且這些基礎數據也常常在有變化調整。這時候須要有一個穩定的數據同步程序,能分批同步基礎數據,因爲網絡流量,網絡的穩定性等因素,須要分批讀取有更新過的數據,花費了半天時間寫了一個例子代碼,客戶端同步從服務器上同步基礎數據的功能,能夠提供給你們參考一下,但願能有重複利用的價值。sql
// 1:打開業務數據庫 SqLiteHelper dbHelper = new SqLiteHelper(BaseSystemInfo.BusinessDbConnection); // 2: 先保存個同步時間標誌,什麼時間成功同步過本地數據庫?這樣不用每次都同步全部的數據,只同步那個時間以後的數據就能夠了。 BaseParameterManager parameterService = new BaseParameterManager(dbHelper, BaseSystemInfo.UserInfo); // 3:用參數的方式讀取同步時間 string synchronous = parameterService.GetParameter("System", BaseOrganizeEntity.TableName, "Synchronous"); // 4: 傳遞參數用的,爲了防注入漏洞的 List<KeyValuePair<string, object>> dbParameters = new List<KeyValuePair<string, object>>(); // 5:只獲取有效的,未被刪除的數據,(數據有被刪除,也應該能同步才能夠) string whereConditional = string.Empty; // string whereConditional = BaseOrganizeEntity.FieldDeletionStateCode + " = 0 AND " + BaseOrganizeEntity.FieldEnabled + " = 1 "; int recordCount = 0; int pageIndex = 1; // 網絡狀況好,客戶端少,每次多獲取一些數據,網絡狀況糟糕每次少獲取一些數據 int pageSize = 500; // 6:不須要獲取全部數據,在最大程度上減小網絡上的數據流量 string selectField = BaseOrganizeEntity.FieldId + "," + BaseOrganizeEntity.FieldCode + "," + BaseOrganizeEntity.FieldFullName + "," + BaseOrganizeEntity.FieldEnabled + "," + BaseOrganizeEntity.FieldDeletionStateCode; int pageCount = 1; if (!string.IsNullOrEmpty(synchronous)) { DateTime modifiedOn = DateTime.Parse(synchronous); dbParameters.Add(new KeyValuePair<string, object>(BaseOrganizeEntity.FieldModifiedOn, modifiedOn)); if (!string.IsNullOrEmpty(whereConditional)) { whereConditional += " AND "; } // 7:只獲取上次同步以後修改過的數據 whereConditional += BaseOrganizeEntity.FieldModifiedOn + " > " + DbHelper.GetParameter(BaseOrganizeEntity.FieldModifiedOn); } // 8:調用遠程服務,獲取須要同步的數據 DotNetService dotNetService = new DotNetService(); DataTable dtSynchronous = dotNetService.UserCenterDbHelperService.GetDataTableByPage(BaseSystemInfo.UserInfo, out recordCount, BaseOrganizeEntity.TableName, selectField, pageIndex, pageSize, whereConditional, dbParameters, BaseOrganizeEntity.FieldId); // 9:防止網絡鏈接超時,把網絡鏈接釋放掉 if (dotNetService.UserCenterDbHelperService is ICommunicationObject) { ((ICommunicationObject)dotNetService.UserCenterDbHelperService).Close(); } // 取得總頁數 if (recordCount % pageSize == 0) { pageCount = recordCount / pageSize; } else { pageCount = recordCount / pageSize + 1; } BaseOrganizeManager organizeManager = null; // 10:按每頁進行循環獲取,也防止數據庫鏈接超時,網絡鏈接超時,每次獲取一部分數據 while (dtSynchronous != null && dtSynchronous.Rows.Count > 0) { BaseOrganizeEntity organizeEntity = null; // 11:防止本地數據庫鏈接超時,每次從新打開一個數據庫鏈接,這樣保險一些 organizeManager = new BaseOrganizeManager(dbHelper, BaseSystemInfo.UserInfo); foreach (DataRow dr in dtSynchronous.Rows) { // 12:不用實體化其實也能夠的,先實體化吧,代碼規範一些 organizeEntity = new BaseOrganizeEntity(); organizeEntity.Id = int.Parse(dr[BaseOrganizeEntity.FieldId].ToString()); organizeEntity.Code = dr[BaseOrganizeEntity.FieldCode].ToString(); organizeEntity.FullName = dr[BaseOrganizeEntity.FieldFullName].ToString(); organizeEntity.Enabled = int.Parse(dr[BaseOrganizeEntity.FieldEnabled].ToString()); organizeEntity.DeletionStateCode = int.Parse(dr[BaseOrganizeEntity.FieldDeletionStateCode].ToString()); // 13: 先按更新操做。 SQLBuilder sqlBuilder = new SQLBuilder(dbHelper); sqlBuilder.BeginUpdate(BaseOrganizeEntity.TableName); sqlBuilder.SetValue(BaseOrganizeEntity.FieldCode, organizeEntity.Code); sqlBuilder.SetValue(BaseOrganizeEntity.FieldFullName, organizeEntity.FullName); sqlBuilder.SetValue(BaseOrganizeEntity.FieldEnabled, organizeEntity.Enabled); sqlBuilder.SetValue(BaseOrganizeEntity.FieldDeletionStateCode, organizeEntity.DeletionStateCode); sqlBuilder.SetWhere(BaseOrganizeEntity.FieldId, organizeEntity.Id); if (sqlBuilder.EndUpdate() == 0) { // 14: 若沒找到數據,進行插入操做。 sqlBuilder.BeginInsert(BaseOrganizeEntity.TableName); sqlBuilder.SetValue(BaseOrganizeEntity.FieldId, organizeEntity.Id); sqlBuilder.SetValue(BaseOrganizeEntity.FieldCode, organizeEntity.Code); sqlBuilder.SetValue(BaseOrganizeEntity.FieldFullName, organizeEntity.FullName); sqlBuilder.SetValue(BaseOrganizeEntity.FieldEnabled, organizeEntity.Enabled); sqlBuilder.SetValue(BaseOrganizeEntity.FieldDeletionStateCode, organizeEntity.DeletionStateCode); sqlBuilder.EndInsert(); } // 15: 這個代碼是按實體進行更新同步的代碼例子。 // 如有缺乏字段什麼的,也鬧心 // if (organizeManager.UpdateObject(organizeEntity) == 0) // { // organizeManager.AddObject(organizeEntity); // } } // 16: 看是否有必要繼續獲取數據,判斷頁數,若不必能少循環一次就少循環一次 dtSynchronous = null; if (pageIndex < pageCount) { // 17: 若數據沒獲取好,繼續獲取數據 pageIndex++; dotNetService = new DotNetService(); dtSynchronous = dotNetService.UserCenterDbHelperService.GetDataTableByPage(BaseSystemInfo.UserInfo, out recordCount, BaseOrganizeEntity.TableName, selectField, pageIndex, pageSize, whereConditional, dbParameters, BaseOrganizeEntity.FieldId); if (dotNetService.UserCenterDbHelperService is ICommunicationObject) { ((ICommunicationObject)dotNetService.UserCenterDbHelperService).Close(); } } } // 18: 更新數據庫中的同步時間標誌。 parameterService.SetParameter("System", BaseOrganizeEntity.TableName, "Synchronous", DateTime.Now.ToString(BaseSystemInfo.DateTimeFormat));