代码之家  ›  专栏  ›  技术社区  ›  James Gardner

如何避免每次更改Windows工作流时重建数据库

  •  0
  • James Gardner  · 技术社区  · 15 年前

    我正在将Windows工作流构建到.NET Web应用程序中。我遇到的问题是,每当我在状态机中添加、删除或更改一个活动,然后重新编译和运行它时,它就不再符合数据库中用于跟踪和持久性的内容。它不会更新更改,也不会在数据库中创建工作流的新版本,而是引发错误。有时它是一个“索引越界”错误,有时它的“无法获取成员XXXXX”。

    为了让它工作,我必须删除数据库并重新构建它。我相信这是可行的,因为当工作流引擎在数据库中查找工作流时,它找不到该工作流,因此将其添加到数据库中。这在我所处的阶段是非常令人沮丧的,在那里我正在构建工作流,并且它在一天中会发生多次更改。

    有没有一种方法可以让工作流引擎使用我对工作流所做的更改来更新数据库中的相关表?或者用新版本覆盖它?我查看过各种关于在运行时设置动态更新工作流的网页,但这些建议对我来说都不起作用。虽然这是我想要的工作流程特性,但我不确定它是否真的是解决我所遇到的问题的方法。与其说我正在创建工作流的新版本,不如说我正在构建工作流,并希望测试刚刚完成/添加的部分,我不关心工作流的早期版本以及数据库中任何部分完成的工作流。

    谢谢。

    1 回复  |  直到 15 年前
        1
  •  1
  •   ksa    15 年前

    我也面临着类似的问题,每当工作流设计发生变化时,数据库中的所有旧工作流实例都会使用抛出错误。

    为了克服这个问题,我为每种类型的工作流创建了跟踪配置文件。如果我更改了任何工作流,我将更新配置文件的版本。这对我很有用……这是示例代码-

    为此,您需要将跟踪服务添加到工作流运行时。

    trackingprofile profile=createprofile();

    storeprofiletodb(profile,connstring,typeof(exceptionwf.parametereexceptionwf),“2.0.0.0”);

    专用静态跟踪配置文件createprofile() { trackingprofile myprofile=new trackingprofile();

            ActivityTrackingLocation stateActivityLocation = CreateActivityLocation(typeof(StateActivity));
            AddActivityExecutionStatus(stateActivityLocation);
    
            ActivityTrackingLocation eventDrivenActLoc = CreateActivityLocation(typeof(EventDrivenActivity));
            AddActivityExecutionStatus(eventDrivenActLoc);
    
            ActivityTrackPoint actPt = new ActivityTrackPoint();
    
            actPt.MatchingLocations.Add(stateActivityLocation);
            actPt.MatchingLocations.Add(eventDrivenActLoc);
            myProfile.ActivityTrackPoints.Add(actPt);
    
            WorkflowTrackPoint workflowTrack = CreateWorkflowTrackPoint();
            myProfile.WorkflowTrackPoints.Add(workflowTrack);
    
            UserTrackPoint utp = new UserTrackPoint();
            UserTrackingLocation ul = new UserTrackingLocation();
            ul.ActivityType = typeof(HandleExternalEventActivity);
            ul.ArgumentType = typeof(object);
            ul.MatchDerivedArgumentTypes = true;
            ul.MatchDerivedActivityTypes = true;
            utp.MatchingLocations.Add(ul);
    
            myProfile.UserTrackPoints.Add(utp);
            myProfile.Version = new Version("1.0.0.0");
            return myProfile;
        }
    
        private static void StoreProfileToDB(TrackingProfile profile, string connString, Type wfType,string version)
        {
            TrackingProfileSerializer serializer = new TrackingProfileSerializer();
            System.IO.StringWriter writer = new System.IO.StringWriter(new StringBuilder());
            serializer.Serialize(writer, profile);
            SqlConnection conn = null;
            try
            {
                if (!String.IsNullOrEmpty(connString))
                {
                    conn = new SqlConnection(connString);
    
    
                    string storedProc = "dbo.UpdateTrackingProfile";
                    SqlCommand cmd = new SqlCommand(storedProc, conn);
                    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    
                    SqlParameter param = new SqlParameter("@TypeFullName", SqlDbType.NVarChar, 128);
                    param.Direction = ParameterDirection.Input;
                    param.Value = wfType.FullName;
                    cmd.Parameters.Add(param);
    
    
                    param = new SqlParameter("@AssemblyFullName", SqlDbType.NVarChar, 256);
                    param.Direction = ParameterDirection.Input;
                    param.Value = wfType.Assembly.FullName;
                    cmd.Parameters.Add(param);
    
    
                    param = new SqlParameter("@Version", SqlDbType.VarChar, 32);
                    param.Direction = ParameterDirection.Input;
                    //Note that you should increment version number for your
                    //TrackingProfile to be able to use new TrackingProfile.
                    //Default version is "1.0.0.0, It uses the default profile if not increamented.
                    param.Value = version;
                    cmd.Parameters.Add(param);
    
                    param = new SqlParameter("@TrackingProfileXml", SqlDbType.NText);
                    param.Direction = ParameterDirection.Input;
                    param.Value = writer.ToString();
                    cmd.Parameters.Add(param);
    
                    conn.Open();
                    cmd.ExecuteNonQuery();
    
                }//if
            }// try
            catch (Exception ex)
            {
                if (ex is SqlException)
                {
                    //Check to see if it's a version error
                    if (ex.Message.Substring(0, 24) == "A version already exists")
                    {
                        EventLogger.Log("A profile with the same version already exists in database");
                    }//if
                    else
                    {
                        EventLogger.Log("Error writing profile to database : " + ex.ToString());
                    }
                }
                else
                {
                    EventLogger.Log("Error writing profile to database : " + ex.ToString());
                }
            }
            finally
            {
                if (conn != null) { conn.Close(); }
            }
        }
    
    推荐文章