做为一个完整的总体信息化解决方案须要有足够强大的各类功能,这些功能相对独立,又互相依存。当有须要这样的功能时能够随时拿出来用,适当修改一下就能够知足要求。只有这样才能快速开发各类信息化系统,才能知足各类客户的需求。web
同步数据须要解决的问题主要有:sql
01:全国性大型集团公司的信息化改造项目会涉及到很是多的分公司网点的客户端须要同步数据的各类需求,这个已经超越了人工能处理好的极限。
02:网点很是多时,每每因为业务的特殊性会有能离线做业的须要,网络故障、网络带宽不理想时均可以进行离线处理的工做流程须要。
03:也因为网络安全缘由、工做特殊缘由,必须有些数据须要在本地网络里处理好,而后经过特殊专线等进行定时上传上报业务数据。
04:手持移动设备等、因为工做环境没有实时的互联网条件、可能也须要在离线条件下处理好数据,链接上网络时再把数据上传到总部。
05:有从大型数据库同步到桌面数据库的须要,例如服务器是SQLServer的、客户端是SQLite的。
06:也有多是服务器与服务器之间的数据同步,例如生产主要数据库同步到统计数据库,同步到查询数据库里。
07:服务器上的总部数据库可能很庞大,每一个网点可能只须要同步部分数据库,甚至是特殊限制的sql语句获取的数据部分须要同步。
08:若须要同步的数据比较多时,因为网络带宽、服务器的稳定性考虑,须要有提供批次获取数据的功能,能够分批获取数据。
09:表结构有变更时;有增长、有减小、有变动是、不要有问题故障发生;能够平稳升级、能够平稳同步数据。
10:如有上万信息终端,若没有数据就不须要进行任何sql语句查询了,减轻中心数据库查询压力。
11:能够访问的库、容许同步的表进行权限控制,防止越权获取不该该看到的数据。
12:接口调用的安全性保证、如何防止恶意调用等,对一个对外开放的接口,这些都须要考虑风险。
13:升级同步还能够能灵活扩展、能执行SQL语句,能编写C#逻辑控制代码。
14:同步程序能够在后台进行、不影响主要业务功能、不影响业务操做。
15:代码简洁、好维护、好调试、好改进,好快速增长同步额外的数据表等。数据库
参考代码以下:安全
//----------------------------------------------------------------- // All Rights Reserved , Copyright (C) 2015 , Hairihan TECH, Ltd. //----------------------------------------------------------------- using System; using System.Collections.Specialized; using System.Data; using System.Net; using System.Text; using Newtonsoft.Json; namespace DotNet.Win { using DotNet.Business; using DotNet.Utilities; /// <summary> /// 数据同步类 /// </summary> public partial class Synchronous { /// <summary> /// 远程数据同步的工具类 /// </summary> /// <param name="fromDataBase">从服务器的哪一个数据库获取数据</param> /// <param name="tableName">同步哪一个表</param> /// <param name="primaryKeys">表的主键是什么</param> /// <param name="modifiedOn">同步的更新时间</param> /// <param name="toDataBaseDbType">同步到本地什么类型的数据库里?</param> /// <param name="dbConnection">同步的目标数据库链接方式?</param> /// <returns>影响行数</returns> public static int SynchronousTable(string fromDataBase, string tableName, string[] primaryKeys, DateTime? modifiedOn, CurrentDbType toDataBaseDbType, string dbConnection) { int result = 0; // 输入参数检查 if (primaryKeys == null) { return result; } int topLimit = 200; DataTable dataTable = null; IDbHelper dbHelper = null; dbHelper = DbHelperFactory.GetHelper(toDataBaseDbType, dbConnection); SQLBuilder sqlBuilder = new SQLBuilder(dbHelper); while (topLimit == 200) { string url = BaseSystemInfo.WebHost + "WebAPIV42/API/Synchronous/GetTopLimitTable"; WebClient webClient = new WebClient(); NameValueCollection postValues = new NameValueCollection(); postValues.Add("userInfo", BaseSystemInfo.UserInfo.Serialize()); postValues.Add("systemCode", BaseSystemInfo.SystemCode); postValues.Add("securityKey", BaseSystemInfo.SecurityKey); postValues.Add("dataBase", fromDataBase); postValues.Add("tableName", tableName); postValues.Add("topLimit", topLimit.ToString()); postValues.Add("modifiedOn", modifiedOn.Value.ToString(BaseSystemInfo.DateTimeFormat)); // 向服务器发送POST数据 byte[] responseArray = webClient.UploadValues(url, postValues); string response = Encoding.UTF8.GetString(responseArray); if (!string.IsNullOrEmpty(response)) { dataTable = (DataTable)JsonConvert.DeserializeObject(response, typeof(DataTable)); } int r = 0; // 出错的日志都须要能保存起来,这样有问题的能够找出缘由来。 for (r = 0; r < dataTable.Rows.Count; r++) { // 先删除数据,修改的、新增的、都删除后添加来处理,问题就简单化了 // dbHelper.ExecuteNonQuery("DELETE FROM " + tableName + " WHERE " + primaryKey + " = '" + dataTable.Rows[r][primaryKey].ToString() + "'"); sqlBuilder.BeginDelete(tableName); for (int i = 0; i < primaryKeys.Length; i++) { string primaryKey = primaryKeys[i]; if (string.IsNullOrWhiteSpace(primaryKey)) { sqlBuilder.SetWhere(primaryKey, dataTable.Rows[r][primaryKey].ToString()); } } sqlBuilder.EndDelete(); // 而后插入数据 sqlBuilder.BeginInsert(tableName); for (int i = 0; i < dataTable.Columns.Count; i++) { // 这里能判断目标表里是否有这个字段存在就更完美了。 sqlBuilder.SetValue(dataTable.Columns[i].ColumnName, dataTable.Rows[r][dataTable.Columns[i].ColumnName]); } sqlBuilder.EndInsert(); if (DateTime.Parse(dataTable.Rows[r][BaseBusinessLogic.FieldModifiedOn].ToString()) > modifiedOn.Value) { modifiedOn = DateTime.Parse(dataTable.Rows[r][BaseBusinessLogic.FieldModifiedOn].ToString()); } result++; } topLimit = dataTable.Rows.Count; } return result; } } }