private static WfProcessCollection DataTableToProcessCollection(DataTable table)
        {
            WfProcessCollection result = new WfProcessCollection();

            XElementFormatter formatter = new XElementFormatter();

            formatter.OutputShortType = WorkflowSettings.GetConfig().OutputShortType;

            foreach (DataRow row in table.Rows)
            {
                WfProcessInstanceData instanceData = new WfProcessInstanceData();

                ORMapping.DataRowToObject(row, instanceData);

                XElement extData = GetExtData(instanceData.ExtData);

                Encoding originalEncoding = GetEncodingFromExtData(extData);
                Encoding preferedEncoding = originalEncoding;
                byte[]   decompressedData = null;

                if (null != instanceData.BinaryData)
                {
                    PerformanceMonitorHelper.GetDefaultMonitor().WriteExecutionDuration(string.Format("Extra Process Data:{0}", instanceData.InstanceID),
                                                                                        () => decompressedData = CompressManager.ExtractBytes(instanceData.BinaryData));

                    PerformanceMonitorHelper.GetDefaultMonitor().WriteExecutionDuration("EncodeProcessString", () =>
                    {
                        preferedEncoding  = GetPreferedEncoding(decompressedData, originalEncoding);
                        instanceData.Data = BytesToProcessData(decompressedData, preferedEncoding);
                    }
                                                                                        );
                }
                else
                {
                    (instanceData.Data != null).FalseThrow <ArgumentException>(Translator.Translate(Define.DefaultCulture, "流程实例表的Data和BinaryData都为空"));
                }

                XElement root = null;

                try
                {
                    root = XElement.Parse(instanceData.Data);
                }
                catch (System.Xml.XmlException)
                {
                    if (decompressedData != null)
                    {
                        instanceData.Data = ChangeEncoding(decompressedData, preferedEncoding);
                        root = XElement.Parse(instanceData.Data);
                    }
                    else
                    {
                        throw;
                    }
                }

                extData.SetAttributeValue("encoding", originalEncoding.BodyName);

                WfProcess process = null;

                PerformanceMonitorHelper.GetDefaultMonitor().WriteExecutionDuration(string.Format("Deserialize Process:{0}", instanceData.InstanceID),
                                                                                    () => process = (WfProcess)formatter.Deserialize(root));

                process.LoadingType = DataLoadingType.External;
                process.Activities.ForEach(a =>
                {
                    ((WfActivityBase)a).LoadingType = DataLoadingType.External;
                    WfActivityBuilderBase.LoadActions(a);
                });
                process.UpdateTag = instanceData.UpdateTag;
                process.Context["SerilizationExtData"] = extData.ToString();

                result.Add(process);
            }

            return(result);
        }
        public void SaveProcess(IWfProcess process)
        {
            WfProcessInstanceData instanceData = WfProcessInstanceData.FromProcess(process);

            if (instanceData.Data.IsNotEmpty())
            {
                if (WorkflowSettings.GetConfig().Compressed)
                {
                    XElement extData = GetExtData(instanceData.ExtData);

                    PerformanceMonitorHelper.GetDefaultMonitor().WriteExecutionDuration("CompressProcess", () =>
                    {
                        instanceData.BinaryData = GetCompressedStream(instanceData.Data, Encoding.GetEncoding(extData.Attribute("encoding", "utf-8")));
                        instanceData.Data       = string.Empty;
                    });
                }
            }

            string sql = string.Empty;

            ORMappingItemCollection mapping = ORMapping.GetMappingInfo <WfProcessInstanceData>();

            if (process.LoadingType == DataLoadingType.External)
            {
                UpdateSqlClauseBuilder uBuilder = ORMapping.GetUpdateSqlClauseBuilder(instanceData, mapping);

                uBuilder.AppendItem("UPDATE_TAG", "UPDATE_TAG + 1", "=", true);
                uBuilder.AppendTenantCode();

                WhereSqlClauseBuilder whereBuilder = ORMapping.GetWhereSqlClauseBuilderByPrimaryKey(instanceData, mapping);

                whereBuilder.AppendItem("UPDATE_TAG", process.UpdateTag);

                sql = string.Format("UPDATE {0} SET {1} WHERE {2}",
                                    mapping.TableName, uBuilder.ToSqlString(TSqlBuilder.Instance), whereBuilder.ToSqlString(TSqlBuilder.Instance));
            }
            else
            {
                InsertSqlClauseBuilder iBuilder = ORMapping.GetInsertSqlClauseBuilder(instanceData, mapping);
                iBuilder.AppendTenantCode();

                sql = string.Format("INSERT INTO {0} {1}", mapping.TableName, iBuilder.ToSqlString(TSqlBuilder.Instance));
            }

            Dictionary <object, object> context = new Dictionary <object, object>();

            using (TransactionScope scope = TransactionScopeFactory.Create())
            {
                PerformanceMonitorHelper.GetDefaultMonitor().WriteExecutionDuration("WriteProcessToDB", () =>
                                                                                    (DbHelper.RunSql(sql, GetConnectionName()) > 0).FalseThrow <WfRuntimeException>(
                                                                                        Translator.Translate(Define.DefaultCulture, "更新流程{0}失败,流程状态已经改变", process.ID))
                                                                                    );

                PerformanceMonitorHelper.GetDefaultMonitor().WriteExecutionDuration("WriteProcessActivitiesToDB",
                                                                                    () => WfProcessCurrentActivityAdapter.Instance.UpdateProcessActivities(process));

                PerformanceMonitorHelper.GetDefaultMonitor().WriteExecutionDuration("WriteRelativeProcessInfoToDB", () =>
                {
                    WfRelativeProcessAdapter.Instance.Delete(new WfRelativeProcess()
                    {
                        ProcessID = process.ID
                    });

                    if (process.RelativeID.IsNotEmpty())
                    {
                        WfRelativeProcessAdapter.Instance.Update(new WfRelativeProcess()
                        {
                            Description = string.IsNullOrEmpty(process.Descriptor.Description) ? process.Descriptor.Name : process.Descriptor.Description,
                            ProcessID   = process.ID,
                            RelativeID  = process.RelativeID,
                            RelativeURL = process.RelativeURL
                        });
                    }
                });

                if (WorkflowSettings.GetConfig().SaveRelativeData)
                {
                    PerformanceMonitorHelper.GetDefaultMonitor().WriteExecutionDuration("WriteRelativeDataToDB",
                                                                                        () => WfExtraPersistenceSettings.GetConfig().GetPersisters().SaveData(process, context));
                }

                scope.Complete();
            }
        }