【问题标题】:How do I avoid rebuilding my database everytime I make a change to my Windows Workflow每次更改 Windows 工作流程时如何避免重建数据库
【发布时间】:2009-07-17 00:58:21
【问题描述】:

我正在将一个 Windows 工作流构建到一个 .Net webapp 中。我遇到的问题是,每次我在状态机中添加、删除或更改活动,然后重新编译并运行它时,它不再匹配数据库中用于跟踪和持久性的内容。它不会更新更改或在数据库中创建新版本的工作流,而是会引发错误。有时是“索引超出范围”错误,有时是“无法获取成员 XXXXX”。

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

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

谢谢。

【问题讨论】:

    标签: workflow workflow-foundation


    【解决方案1】:

    我也遇到过类似的问题,每次工作流设计发生变化,数据库中所有旧的工作流实例都会抛出错误。

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

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

    TrackingProfile 配置文件 = CreateProfile();

    StoreProfileToDB(profile, connString, typeof(ExceptionWF.ParameterExceptionWF),"2.0.0.0");

    私有静态 TrackingProfile 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(); }
            }
        }
    

    【讨论】:

    • 除了配置文件跟踪另一个选项是将多个工作流版本加载到全局程序集缓存中。好消息是这在 .NET4.0 中不会成为问题。 4 的坏消息将在明年某个时候发布。
    • @ksa - 您是否手动增加版本号?也就是说,如果你改变你的工作流程,在你重新编译之前你会在源代码中增加版本号吗?我尝试通过将我的数据库中的跟踪配置文件与刚刚创建的配置文件进行比较来做类似的事情,如果它们不同,我会更新配置文件并增加版本,但我不断收到我不能的数据库错误解决。 @ahsteele - 我也试过了,但又失败了……上周对我来说赢的并不多!我会再试一次。 :-)
    • 您的意思是说,在更改配置文件版本后,您“更新”数据库,如果是,那么这就是问题所在。数据库中的旧工作流实例仍需要旧的配置文件版本。当您更改工作流程设计时,只需更新代码中的配置文件版本(因为您更改了设计或工作流程代码)。 Db 现在应该必须分析相同工作流类型的版本。希望这会有所帮助。
    • 我又回到了这个问题上,因为我的跟踪功能根本不起作用。我在代码示例中注意到 xml 中的配置文件版本与存储在 Db 字段中的配置文件版本不同。这是故意的吗?我认为它们应该是一样的。
    猜你喜欢
    • 1970-01-01
    • 2013-09-20
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 2014-12-04
    • 2020-06-29
    相关资源
    最近更新 更多