/// <summary> /// 直接创建目录 /// </summary> /// <param name="dirId"></param> /// <param name="dirName"></param> /// <returns></returns> protected bool AddDirDirectly(ref string dirId, string dirName, DirTypeEnum dirType, string parentDirId) { if (string.IsNullOrEmpty(dirName)) { return(false); } if (parentDirId == null) { parentDirId = string.Empty; } Dictionary <string, LibChangeRecord> dicChanges = new Dictionary <string, LibChangeRecord>(); Dictionary <string, object> dicChangeColumns = new Dictionary <string, object>(); LibEntryParam entryParam = new LibEntryParam(); entryParam.ParamStore.Add("ParentDirId", parentDirId); entryParam.ParamStore.Add("ParentDirType", (int)dirType); this.DataSet.Clear(); this.AddNew(entryParam); if (this.ManagerMessage.IsThrow) { return(false); } if (string.IsNullOrEmpty(dirId)) { dirId = LibSysUtils.ToString(this.DataSet.Tables[0].Rows[0]["DIRID"]); } object[] pks = new object[] { dirId }; //因对于Add的对象Save方法中会检查Add的第一条记录数据并做相关处理,因此需要模拟生成前端传递来的change数据 LibChangeRecord record = new LibChangeRecord(); foreach (DataColumn col in this.DataSet.Tables[0].Columns) { dicChangeColumns.Add(col.ColumnName, this.DataSet.Tables[0].Rows[0][col.ColumnName]);//将文档主表的第一行数据变成change数据 } dicChangeColumns["DIRID"] = dirId; dicChangeColumns["DIRNAME"] = dirName; dicChangeColumns["DIRTYPE"] = (dirType == DirTypeEnum.Public) ? 0 : 1; dicChangeColumns["PARENTDIRID"] = parentDirId; record.Add.Add(dicChangeColumns); dicChanges.Add("DMDIRECTORY", record); this.DataSet.Clear();//将通过addNew添加的数据全清空,以免和通过change数据添加的重复了。 this.Save(BillAction.AddNew, pks, dicChanges, null); if (this.ManagerMessage.IsThrow) { return(false); } else { return(true); } }
/// <summary> /// 同步数据。 /// 可以由其他站点通过令牌信息跨站点调用 /// </summary> /// <param name="billAction">业务操作类型</param> /// <param name="mainRowPks">主数据的主键值</param> /// <param name="subDeleteChanges">子表或子子表中删除行的信息</param> /// <param name="extendBcfParam">扩展参数信息</param> /// <param name="dataSet">数据集信息</param> public virtual void SynchroData(BillAction billAction, Dictionary <string, object> mainRowPks, Dictionary <string, LibChangeRecord> subDeleteChanges, Dictionary <string, object> extendBcfParam, DataSet dataSet) { if (mainRowPks == null || mainRowPks.Count == 0) { return; } object[] pks = mainRowPks.Values.ToArray(); Dictionary <string, LibChangeRecord> changeRecords = null; Dictionary <string, string> extendParams = null; if (extendBcfParam != null && extendBcfParam.Keys.Count > 0) { extendParams = new Dictionary <string, string>(); foreach (string key in extendBcfParam.Keys) { extendParams[key] = JsonConvert.SerializeObject(extendBcfParam[key]); } } if (billAction == BillAction.Delete) { this.Delete(pks, extendParams); } else { BcfSyncConfig syncConfig = this.Template.FuncPermission.SyncConfig;//同步配置 //先判断当前数据库中是否存在相关数据,并结合BillAction类型重新设定操作类型 LibBcfData newBcf = (LibBcfData)LibBcfSystem.Default.GetBcfInstance(this.ProgId); newBcf.Handle = this.Handle; DataSet thisSiteData = newBcf.BrowseTo(pks); //处理修改状态的委托方法 Action setModifyAction = delegate { dataSet.AcceptChanges(); // 检查每一行与当前数据中的行的对应关系,如果当前不存在则设置为新增状态,否则设置为修改状态 DataTable thisDt = null; DataRow thisRow = null; List <object> keyValueList = new List <object>(); //表主键值 Dictionary <string, object> dicValues = new Dictionary <string, object>(); //数据行的各列的具体值临时存储 int tableCount = -1; foreach (DataTable dt in dataSet.Tables) { tableCount++;//约定主表必须为第一个表 if (thisSiteData.Tables.Contains(dt.TableName) == false) { continue;//本站中不包含的数据表不进行处理 } else { thisDt = thisSiteData.Tables[dt.TableName]; } if (thisDt.PrimaryKey == null || thisDt.PrimaryKey.Length == 0) { continue;//没有主键无法比较数据也直接返回 } int keyColumnCount = 0; List <DataColumn> keyColList = new List <DataColumn>(); foreach (DataColumn col in thisDt.PrimaryKey) { if (dt.Columns.Contains(col.ColumnName)) { keyColumnCount++; keyColList.Add(dt.Columns[col.ColumnName]); } } if (keyColumnCount != thisDt.PrimaryKey.Length) { continue;//主键不一致 } foreach (DataRow row in dt.Rows) { keyValueList.Clear(); if (tableCount == 0)//对于主表,主键值使用传输过来的主键原始值 { keyValueList = mainRowPks.Values.ToList(); } else { foreach (DataColumn col in thisDt.PrimaryKey) { if (dt.Columns.Contains(col.ColumnName)) { if (mainRowPks.Keys.Contains(col.ColumnName))//对于其他表,主键值中包含的主表主键列使用传输过来的原始值 { keyValueList.Add(mainRowPks[col.ColumnName]); } else { keyValueList.Add(row[col.ColumnName]); } } } } if (keyValueList.Count == 0) { continue; } thisRow = thisDt.Rows.Find(keyValueList.ToArray()); if (thisRow == null) { row.SetAdded();//本地不存在的行新增 //检查不需要同步的数据列 if (syncConfig != null && syncConfig.NonSyncFields.Keys.Contains(thisDt.TableName) && syncConfig.NonSyncFields[thisDt.TableName].Count > 0) { foreach (string fieldName in syncConfig.NonSyncFields[thisDt.TableName]) { if (string.IsNullOrEmpty(fieldName) || thisDt.Columns.Contains(fieldName) == false || dt.Columns.Contains(fieldName) == false) { continue; } if (thisDt.Columns[fieldName].AllowDBNull) { row[fieldName] = DBNull.Value;//对于不需要同步的列,新增时直接设置为空。 } } } } else { row.SetModified(); row.BeginEdit(); //通过重置数据,实现原始版本和当前版本不相同 try { foreach (DataColumn col in dt.Columns) { dicValues[col.ColumnName] = row[col]; if (keyColList.Contains(col) == false) { //非主键列直接设置为空,以便实现更改 row[col] = DBNull.Value; } else { if (mainRowPks.Keys.Contains(col.ColumnName)) { row[col] = mainRowPks[col.ColumnName];//子表中与主表中的主键列相同的,原始值设置为传输过来的值 } //子表中的其他主键列,一般为RowID、FormRowID等,都基本是只读的,不会变更。 } } row.AcceptChanges();//先接受修改,然后再改回原来的值,这样实现历史版本和当前版本不一致。 foreach (DataColumn col in dt.Columns) { row[col] = dicValues[col.ColumnName]; } //检查不需要同步的数据列 if (syncConfig != null && syncConfig.NonSyncFields.Keys.Contains(thisDt.TableName) && syncConfig.NonSyncFields[thisDt.TableName].Count > 0) { foreach (string fieldName in syncConfig.NonSyncFields[thisDt.TableName]) { if (string.IsNullOrEmpty(fieldName) || thisDt.Columns.Contains(fieldName) == false || dt.Columns.Contains(fieldName) == false || keyColList.Contains(dt.Columns[fieldName]) // 主键列必须同步 ) { continue; } if (thisDt.Columns[fieldName].ExtendedProperties.ContainsKey(FieldProperty.AllowEmpty) == false) { dt.Columns[fieldName].AllowDBNull = true; row[fieldName] = DBNull.Value;//对于不需要同步的列,直接设置为空。 } } } } finally { row.EndEdit(); } } } dt.PrimaryKey = keyColList.ToArray(); //因直接序列化过来的没有主键,需要重新设置。但要放到模拟实现了数据更改后再设置主键,不然会引起主键为空等错误。 } }; if (billAction == BillAction.AddNew) { //当前系统存在要添加的数据 if (thisSiteData != null && thisSiteData.Tables.Count > 0 && thisSiteData.Tables[0].Rows.Count > 0) { billAction = BillAction.Modif; setModifyAction(); } } else if (billAction != BillAction.Browse) { //除了新增、删除之外的其他操作,只要不是浏览且当前数据库中不存在,操作一律为修改状态 if (thisSiteData == null || thisSiteData.Tables.Count == 0 || thisSiteData.Tables[0].Rows.Count == 0) { billAction = BillAction.AddNew; } else { billAction = BillAction.Modif; setModifyAction(); } } changeRecords = DataSetManager.GetChangeRecord(dataSet); if (billAction == BillAction.AddNew) { this.Save(billAction, pks, changeRecords, extendParams); } else if (billAction == BillAction.Modif) { //处理子表或子子表的删除行信息 LibChangeRecord tableChanges = null; if (subDeleteChanges != null && subDeleteChanges.Count > 0) { foreach (string tableName in subDeleteChanges.Keys) { if (tableName == this.DataSet.Tables[0].TableName) { continue; } if (subDeleteChanges[tableName] == null || subDeleteChanges[tableName].Remove == null || subDeleteChanges[tableName].Remove.Count == 0) { continue; } if (changeRecords.ContainsKey(tableName) == false) { changeRecords[tableName] = subDeleteChanges[tableName]; } else { tableChanges = changeRecords[tableName]; tableChanges.Remove = subDeleteChanges[tableName].Remove; } } } this.Edit(pks);//先编辑实现缓存中有该对象 this.Save(billAction, pks, changeRecords, extendParams); } } }