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

发布于 2024-07-27 22:22:57 字数 551 浏览 1 评论 0原文

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

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

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

谢谢。

I am building a Windows Workflow into a .Net webapp. The problem I have is that every time I add or remove or change an activity in the state machine and then re-compile and run it, it no longer matches up to what is in the database for tracking and persistence. Instead of updating the changes, or creating a new version of the workflow in the database it throws an error. Sometimes it an "index out of bounds" error, other times its "Cannot get the member XXXXX."

To get it to work I have to delete the database and re-build it. I believe this works because when the workflow engine looks for the workflow in the database it doesn't find it and thus adds it to the database. This is very frustrating at the stage I am at, where I am building the workflow and it changes many times in a day.

Is there a way I can simply get the workflow engine to update the relevant tables in the database with the changes I have made to the workflow? Or overwrite it with a new version? I have looked at various webpages on setting up the workflow for dynamic updating at runtime but none of these suggestions worked for me. And whilst that is a feature I would like for my workflow, I am not sure if it is really the way to solve the problem I am having. It is not so much that I am creating a new version of the workflow, rather I am building a workflow and want to test the part I have just finished/added and I don't care about previous versions of the workflow and any partially complete workflows in the database.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱的十字路口 2024-08-03 22:22:57

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

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

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

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(); }
        }
    }

I too faced similar problem , everytime Workflow design was change, all the old workflow instances in the DB use to throw error.

To overcome this , I created Tracking profile for each type of workflow. If I changed any workflow, i updated the version of my profile. This worked for me ..Here is the sample code -

For this you need to add tracking service to workflow runtime .

TrackingProfile profile = CreateProfile();

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

private static 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(); }
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文