2009-07-17 9 views
0

Windowsワークフローを.Net Webアプリケーションに構築しています。私が持っている問題は、ステートマシンでアクティビティを追加または削除したり、アクティビティを変更してから再コンパイルして実行するたびに、トラッキングと永続性のためにデータベース内のものと一致しなくなることです。変更を更新するか、またはデータベースに新しいバージョンのワークフローを作成する代わりに、エラーがスローされます。場合によっては「範囲外のインデックス」エラー、「メンバーXXXXXを取得できません」というエラーがあります。Windows Workflowを変更するたびにデータベースを再構築しないようにするにはどうすればいいですか?

私はデータベースを削除して再構築する必要があります。ワークフローエンジンがデータベース内のワークフローを検索するときに、ワークフローエンジンがそれを見つけずデータベースに追加するため、これはうまくいくと私は信じています。これは私がワークフローを構築している場所で、非常にイライラしていて、1日に何度も変更されます。

ワークフローエンジンを取得して、ワークフローに加えた変更をデータベースの関連テーブルに更新する方法はありますか?または、新しいバージョンで上書きしますか?私は実行時に動的更新のワークフローを設定する際に様々なWebページを見てきましたが、これらの提案のどれも私のために働いていませんでした。それが私のワークフローにとって欲しい機能ですが、実際に私が抱えている問題を解決する方法であるかどうかはわかりません。新しいバージョンのワークフローを作成しているのではなく、ワークフローを構築しています。今完成したばかりの部分をテストしたいと思っています。以前のバージョンのワークフローや部分的に完全なデータベース内のワークフロー。

ありがとうございました。

答えて

1

私も同様の問題に直面していましたが、毎回ワークフロー設計が変更されたため、DB内の古いワークフローインスタンスはすべてエラーをスローします。

これを解決するために、ワークフローの種類ごとにトラッキングプロファイルを作成しました。ワークフローを変更した場合は、私のプロファイルのバージョンを更新しました。これは私のために働いた..サンプルコードはここにあります -

このためには、ワークフローランタイムにトラッキングサービスを追加する必要があります。

TrackingProfile profile = 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(); } 
     } 
    } 
+0

さらに、プロファイルを別の方法で追跡することは、複数のワークフローバージョンをグローバルアセンブリキャッシュに読み込むことです。良いニュースは、これは.NET4.0では問題ではないということです。 4の悪いニュースリリースはいつか来年になるだろう。 – ahsteele

+0

@ksa - あなたは手動でバージョン番号を増やしていますか?つまり、ワークフローを変更した場合、再コンパイルする前に、ソースコードのバージョン番号をバンプアップしますか? 私のデータベースの追跡プロファイルと、作成したものとを比較することで、このようなことを試みました。それらが異なっていた場合は、プロファイルを作成してバージョンを増やすことになりましたが、解決する。 @ahsteele - 私もこれを試しましたが、もう一度失敗しました...先週私のためにたくさんの勝利! 私はもう一度やり直します。 :-) –

+0

あなたは、プロファイルのバージョンを変更した後、DBを "更新"しますか?そうなら、これを問題にしますか? DB内の古いワークフローインスタンスには、古いプロファイルバージョンが必要です。ワークフロー設計を変更するときは、コード内のプロファイルのバージョンを更新するだけです(uは設計コードまたはワークフローコードを変更したためです)。 Dbは、同じワークフロータイプのバージョンをプロファイルする必要があります。お役に立てれば。 – ksa

関連する問題