您的位置:首页 > 其它

第五章 工作流定义工具的设计与实现(三)

2012-09-18 15:04 281 查看
5.7 开发工作流图形定义工具

5.7.2 项目配置文件

配置文件app.config中包含了数据库的连接配置:

<?xml version="1.0" encoding="utf-8"?>

<configuration>

<appSettings>

......

<add key="DBsqlConn" value="data source=(local);initial catalog=myworkflow;

password=mxh;user id=mxh;persist security info=True;"/>

</appSettings>

</configuration>

5.7.3 数据库操作代码文件

与工作流引擎的实现类似,为了增强数据访问的安全性,提高代码编写效率,这里也把对数据库的操作封装在类文件DataAccess.cs中。因为数据访问操作代码与第四章工作流引擎的数据访问基础类Base类似,这里仅列举数据访问操作的部分函数名:

using System;

using System.Data;

using System.Data.SqlClient;

using System.Configuration;

namespace drawtaskbytoolbar

{

public class DataAccess

{

private SqlConnection mAppCon = null;

private string SqlErrDes = "";

public DataAccess()

{

mAppCon = new SqlConnection();

string connstring = ConfigurationSettings.AppSettings["DBsqlConn"];

mAppCon.ConnectionString = connstring;

}

//返回数据库操作异常的公共变量

public string BaseSqlErrDes

{

get

{

return SqlErrDes;

}

}

......

//以sql语句为参数,执行sql修改、添加、删除操作

public bool SQLExeNonQuery( string Sql )

......

//以sql命令对象为参数,执行删除、添加、修改等操作

public bool SQLExeNonQuery( SqlCommand cmd )

//执行事务处理(多语句修改、添加、删除操作)

public bool ExeSQLNonQueryTransaction( string Sql )

......

//sql语句查询,返回dataset

public DataSet SQLExeDataSet(string Sql)

......

//sql语句查询,返回dataset

public DataSet SQLExeDataSet(SqlCommand cmd)

......

//判断是否存在记录

public bool IfExistRecord(SqlCommand cmd)

......

//获取任务定义的编号

public string GetTaskID(string processid,string taskname)

{

string strSql="select TaskID from TaskDefinition where

ProcessID="+processid+" and TaskName='"+taskname+"'";

......

}

}

}

5.7.4 节点定义类文件

1、节点定义类文件NodeClass.cs

using System;

using System.Drawing;

namespace drawtaskbytoolbar

{

public class NodeClass

{

//节点矩形框的左上角坐标,用于定位节点图形

public float LeftTopX;

public float LeftTopY;

//节点矩形的宽度和长度(单位像素)

public int Width;

public int Height;

//节点名称

public string NodeName;

//节点类型(枚举类型变量,后面有定义)

public nodetypedefine NodeType;

//节点的过程逻辑属性(如“AndJoin”,表示并行连接)

public string ProcessLogic="";

//构造函数

public NodeClass()

{

LeftTopX=-1;

LeftTopY=-1;

}

public NodeClass(float x,float y)

{

LeftTopX=x;

LeftTopY=y;

}

//判断是否同一节点

public bool IsSameNode(NodeClass node)

{

if((int)this.LeftTopX == (int)node.LeftTopX & (int)this.LeftTopY

== (int)node.LeftTopY & this.NodeName == node.NodeName)

return true;

else

return false;

}

//判断鼠标点击位置是否在当前节点框内

public bool IsPointInNode(float x,float y)

{

if(x >= this.LeftTopX & y>=this.LeftTopY & x<=this.LeftTopX+this.Width

& y<=this.LeftTopY+this.Height)

return true;

else

return false;

}

}

//记录节点类型的枚举类型定义

public enum nodetypedefine

{

notask=0,start,end,tasknode,andsplit,orsplit,andjoin,orjoin,transition

}

}

2、保存节点集的集合类NodeRecords.cs

using System;

using System.Collections;

using System.Data;

using System.Data.SqlClient;

using System.Windows.Forms;

namespace drawtaskbytoolbar

{

public class NodeRecords

{

//保存所画节点的对象数组

public ArrayList nodeList=new ArrayList();

//空构造函数

public NodeRecords(){}

//添加节点

public bool AddNode(NodeClass node)

{

nodeList.Add(node);

return true;

}

//删除节点

public bool DeleteNode(NodeClass node)

{

for(int i=0;i<nodeList.Count;i++)

{

//节点名称唯一

if(((NodeClass)nodeList[i]).NodeName == node.NodeName)

{

nodeList.RemoveAt(i);

return true;

}

}

return false;

}

//公共属性(节点元素个数)

public int Count

{

get

{

return nodeList.Count;

}

}

//获取节点数组的第i个节点对象

public NodeClass GetNode(int i)

{

if(i>=0 & i<Count)

return (NodeClass)nodeList[i];

else

return null;

}

//根据节点名称获取节点

public NodeClass GetNode(string nodename)

{

for(int i=0;i<nodeList.Count;i++)

{

if(GetNode(i).NodeName == nodename)

return GetNode(i);

}

return null;

}

//判断节点数组中是否包含给定类型的节点

public bool HasNode(nodetypedefine nodetype)

{

for(int i=0;i<nodeList.Count;i++)

{

if(GetNode(i).NodeType == nodetype)

return true;

}

return false;

}

//新增加的节点命名为“任务k”,k始终不大于节点数,每删除或重命名一个,就产生一个

//可重复使用的节点名“任务j”,j<=节点总数,这样就可以把新增加的节点命名为“任务

//j”。这样可以始终保持节点名称的唯一。

//获取新增节点的默认名称

public string GetNewNodeName()

{

string nodename="";

int j=0;

for(int i=1;i<=nodeList.Count+1;i++)

{

nodename="任务"+i;

//在节点集合中找名称为任务i的节点

for(j=0;j<nodeList.Count;j++)

{

if(((NodeClass)nodeList[j]).NodeName == nodename)

break;

}

//如果找不到就退出外层循环,新增节点命名为任务i.否则继续循环.

if(j == nodeList.Count)

break;

}

//如果内外循环都被完整执行,则nodename为"任务"+(nodeList.Count+1)

return nodename;

}

//获取新的逻辑节点名称(保证逻辑节点名称的唯一性)

public string GetNewLogicNodeName(nodetypedefine nodetype)

{

string nodename="";

int j=0;

for(int i=1;i<=nodeList.Count+1;i++)

{

if(nodetype == nodetypedefine.andsplit)

nodename="And Split"+i;

if(nodetype == nodetypedefine.andjoin)

nodename="And Join"+i;

if(nodetype == nodetypedefine.orsplit)

nodename="Or Split"+i;

if(nodetype == nodetypedefine.orjoin)

nodename="Or Join"+i;

//在节点集合中找名称为任务i的节点

for(j=0;j<nodeList.Count;j++)

{

if(((NodeClass)nodeList[j]).NodeName == nodename)

break;

}

//如果找不到就退出外层循环,新增节点命名为任务i.否则继续循环.

if(j == nodeList.Count)

break;

}

//如果内外循环都被完整执行,则nodename为"任务"+(nodeList.Count+1)

return nodename;

}

//保存开始、结束及任务节点到数据库(使用带参数的sql命令是为了增加安全性)

public int SaveProcess(string processname,string tablename,string tablealias,

string identityfield,string
duedate)

{

string strSql"insert into ProcessDefinition(ProcessName,RelatedTable,

Alias,IdentifiedField,DueDate) values(@ProcessName,'"+tablename

+"','"+tablealias+"','"+identityfield+"',@DueDate)";

SqlCommand cmd;

try

{

cmd=new SqlCommand(strSql);

cmd.Parameters.Add("@ProcessName",SqlDbType.VarChar,50);

cmd.Parameters["@ProcessName"].Value=processname;

cmd.Parameters.Add("@DueDate",SqlDbType.SmallInt);

cmd.Parameters["@DueDate"].Value=int.Parse(duedate);

}

catch(System.FormatException ex)

{

MessageBox.Show("数据格式错误!");

return -1;

}

DataAccess database=new DataAccess();

if(! database.SQLExeNonQuery(cmd))

{

MessageBox.Show("保存流程失败!");

return -1;

}

//获取流程编号

strSql="select ProcessID from ProcessDefinition where ProcessName

= @ProcessName"

cmd=new SqlCommand(strSql);

cmd.Parameters.Add("@ProcessName",SqlDbType.VarChar,50);

cmd.Parameters["@ProcessName"].Value=processname;

DataSet ds=database.SQLExeDataSet(cmd);

string processID=ds.Tables[0].Rows[0]["ProcessID"].ToString();

//保存所有节点(包括节点名称、节点类型、任务节点包含的过程逻辑等)

string completeSql="";

for(int i=0;i<Count;i++)

{

//保存开始节点

if(GetNode(i).NodeType == nodetypedefine.start)

completeSql=completeSql+"insert into TaskDefinition

(ProcessID,TaskName,NodeType) values("+processID+",'"

+GetNode(i).NodeName+"','Start');";

//保存结束节点

if(GetNode(i).NodeType == nodetypedefine.end)

completeSql=completeSql+"insert into TaskDefinition

(ProcessID,TaskName,NodeType) values("+processID+",'"

+GetNode(i).NodeName+"','End');";

//保存任务节点

if(GetNode(i).NodeType == nodetypedefine.tasknode)

completeSql=completeSql+"insert into TaskDefinition

(ProcessID,TaskName,NodeType,ProcessLogic) values

("+processID+",'"+GetNode(i).NodeName+"','TaskNode','"

+GetNode(i).ProcessLogic+"');";

}

if(completeSql == "")

{

MessageBox.Show("没有可保存的节点!");

return -1;

}

//执行sql事务处理,保证节点保存操作的完整性

if(! database.ExeSQLNonQueryTransaction(completeSql))

{

MessageBox.Show("保存节点失败!"+database.BaseSqlErrDes);

return -1;

}

return int.Parse(processID);

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: