2009-07-17 4 views
0

Ich baue einen Windows-Workflow in eine .Net-Webanwendung ein. Das Problem, das ich habe, besteht darin, dass jedes Mal, wenn ich eine Aktivität in der Zustandsmaschine hinzufüge oder lösche oder ändere und sie dann erneut kompiliere und ausführe, sie nicht mehr mit der Datenbank für Nachverfolgung und Persistenz übereinstimme. Anstatt die Änderungen zu aktualisieren oder eine neue Version des Workflows in der Datenbank zu erstellen, wird ein Fehler ausgegeben. Manchmal ist es ein "Index außerhalb der Grenzen" -Fehler, manchmal ist es "Kann das Mitglied XXXXX nicht bekommen."Wie vermeide ich die Neuerstellung meiner Datenbank bei jeder Änderung an meinem Windows-Workflow?

Um es zum Laufen zu bekommen, muss ich die Datenbank löschen und neu aufbauen. Ich glaube, das funktioniert, denn wenn die Workflow-Engine nach dem Workflow in der Datenbank sucht, findet sie ihn nicht und fügt ihn so zur Datenbank hinzu. Das ist sehr frustrierend in der Phase, in der ich arbeite, wo ich den Arbeitsablauf baue und er sich oft an einem Tag ändert.

Gibt es eine Möglichkeit, ich kann einfach die Workflow-Engine die relevanten Tabellen in der Datenbank mit den Änderungen, die ich an den Workflow gemacht habe, zu aktualisieren? Oder überschreiben Sie es mit einer neuen Version? Ich habe verschiedene Webseiten beim Einrichten des Workflows für die dynamische Aktualisierung zur Laufzeit angeschaut, aber keiner dieser Vorschläge funktionierte für mich. Und obwohl das ein Feature ist, das ich für meinen Workflow haben möchte, bin ich mir nicht sicher, ob es wirklich der Weg ist, das Problem zu lösen, das ich habe. Es ist nicht so sehr, dass ich eine neue Version des Workflows erstelle, sondern ich baue einen Workflow und möchte den Teil testen, den ich gerade beendet/hinzugefügt habe, und ich interessiere mich nicht für vorherige Versionen des Workflows und teilweise unvollständig Workflows in der Datenbank.

Danke.

Antwort

1

Ich konfrontiert auch ähnliches Problem, jedes Mal, wenn Workflow-Design geändert wurde, verwenden alle alten Workflow-Instanzen in der DB Fehler zu werfen.

Um dies zu vermeiden, habe ich Tracking-Profil für jede Art von Workflow erstellt. Wenn ich einen Workflow geändert habe, habe ich die Version meines Profils aktualisiert. Dies funktioniert für mich .. Hier ist der Beispielcode -

Dazu müssen Sie Tracking-Service Workflow-Laufzeit hinzufügen.

TrackingProfile-Profil = CreateProfile();

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

private statische 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

Darüber hinaus Profilverfolgung eine andere Option ist das Laden der mehreren Workflow-Versionen in Ihrem globalen Assemblycache. Die gute Nachricht ist, dass dies in .NET 4.0 kein Problem ist. Die schlechte Nachricht von 4 wird irgendwann im nächsten Jahr sein. – ahsteele

+0

@ksa - erhöhen Sie die Versionsnummer von Hand? Das heißt, wenn Sie Ihren Workflow ändern, erhöhen Sie vor dem erneuten Kompilieren die Versionsnummer im Quellcode. Ich habe versucht, so etwas zu tun, indem ich das Tracking-Profil in meiner Datenbank mit dem gerade erstellten verglichen habe und wenn sie anders waren, würde ich das Profil updaten und die Version inkrementieren, aber ich bekam weiterhin db-Fehler, die ich nicht konnte. t lösen. @ahsteele - Ich habe das auch versucht, aber wieder gescheitert ... nicht viele Gewinne für mich letzte Woche! Ich werde es erneut versuchen. :-) –

+0

Willst du sagen, nach dem Ändern der Profilversion "aktualisierst" du die DB, wenn ja dann das das Problem ist. Die alten Workflow-Instanzen in Ihrer Datenbank benötigen weiterhin die alten Profilversionen. Wenn Sie Ihr Workflow-Design ändern, aktualisieren Sie einfach die Version des Profils im Code (seit Sie den Design- oder Workflow-Code geändert haben). Der DB sollte jetzt Versionen desselben Workflow-Typs profilieren müssen. Hoffe das hilft. – ksa

Verwandte Themen