3

Entity Framework 4 と POCO を使用して、DB (この場合は SQL Server Compact) のテーブルを更新するカスタム アクティビティをいくつか作成しました。

これらを WF4 TransactionScope アクティビティ内に複数配置すると、問題が発生します。EF は、最初のアクティビティが終了した後に DB 接続を破棄し、次の DB アクティビティが DB 更新を実行しようとすると、新しい接続が構築されます。上。この時点で例外がスローされます。

System.Activities.WorkflowApplicationAbortedException : The workflow has been aborted.
 ----> System.Data.EntityException : The underlying provider failed on Open.
 ----> System.InvalidOperationException : The connection object can not be enlisted in transaction scope.

トランザクション スコープ全体で EF 接続を開いたままにしておく必要がありますか? どうやってやるの?そのための明示的なカスタム アクティビティを作成しますか、それとも標準的な方法はありますか?

私の現在の回避策は次のようになります: ObjectContext を作成し、明示的に dbContext.Connection.Open() を呼び出す新しいコード アクティビティを作成しました。ObjectContext が返され、ワー​​クフロー変数に保存されます。これは、DB 関連のすべてのアクティビティに InArgument<> として渡されます。DB アクティビティ内で、渡された場合はこの ObjectContext を使用し、そうでない場合は新しいものを作成します。

これは機能しますが、この解決策には満足できません。DB 関連のアクティビティごとに新しい InArgument が必要です。ワークフロー デザイナーでは、その特別な OpenDatabaseConnection アクティビティをトランザクション スコープ内に挿入し、正しい変数がすべての DB アクティビティに渡されるようにする必要があります。これは、特に他のチーム メンバーがこれらの DB アクティビティを使用する必要がある場合、非常に洗練されておらず、エラーが発生しやすいようです。

これを処理するより良い方法は何でしょうか?

4

1 に答える 1

1

問題は、同じトランザクションスコープで2番目の接続を開くと、トランザクションを分散トランザクションに昇格させようとすることです(同じデータベースに接続しているため、分散トランザクションは何もありませんが)。SQL Server CEは、このシナリオをサポートしていません。

私が行うことは、接続を開いて(そして閉じて)子アクティビティで利用できるようにするカスタムの「コンテナ」アクティビティを作成することです。これはまだ最適ではありませんが、少なくとも、を渡す必要はありませんInArgument。次のアクティビティツリーが表示されます。

TransactionScope
    InitializeConnection
        Sequence
            CustomDataActivity1
            CustomDataActivity2
            CustomDataActivity3

InitializeConnectionは、子アクティビティへの接続(または)を公開するためNativeActivityに使用します。NativeActivityContext.PropertiesObjectContext

常に接続を閉じるように、適切なエラー処理を実装してください。

注:分散トランザクションは、 MSDTC(Microsoft分散トランザクションコーディネーター)と呼ばれるWindowsサービスを介してのみ完全なSQLServerでサポートされます。これは「ローカルサービス」にあります。SQL Server CEは完全にスタンドアロンで動作できるデータベースであるため、MSDTCに依存しないことは理にかなっています。したがって、分散トランザクションはサポートされていません。

于 2012-10-08T12:27:25.937 に答える