2011-02-09 11 views
0

私のアプローチでは、3つのdataprovider.GetXXXメソッドをUnitOfWorkというサービス層のTransactionScopeにすべてバンドルする方法がありますか?UnitOfWork操作のService LayerでTransactionScopeを使用

あなたは何か違うことをしますか?

具体的なConnectionStringは、どこからTransactionScopeが知るのですか?

私の接続からトランザクションオブジェクトを取得し、このトランザクションオブジェクトをTransactionScopeのコンストラクタに渡す必要がありますか? AdministrationService.csよう

サービス層データプロバイダのもの3つの方法のいずれかのように見える可能性がどのように

private List<Schoolclass> GetAdministrationData() 
{ 

    List<Schoolclass> schoolclasses = null 
    using (TransactionScope ts = new TransactionScope()) 
        { 
         schoolclasses = _adminDataProvider.GetSchoolclasses(); 
         foreach (var s in schoolclasses) 
         { 
          List<Pupil> pupils = _adminDataProvider.GetPupils(s.Id); 
          s.Pupils = pupils; 

          foreach (var p in pupils) 
          { 
           List<Document> documents = _documentDataProvider.GetDocuments(p.Id); 
           p.Documents = documents; 
          } 
         } 

         ts.Complete(); 
        } 


    return schoolclasses; 
} 

サンプル:

public List<Schoolclass> GetSchoolclassList() 
     { 
      // used that formerly without TransactionSCOPE => using (var trans = DataAccess.ConnectionManager.BeginTransaction()) 
      using (var com = new SQLiteCommand(DataAccess.ConnectionManager)) 
      { 
       com.CommandText = "SELECT * FROM SCHOOLCLASS"; 

       var schoolclasses = new List<Schoolclass>(); 

       using (var reader = com.ExecuteReader()) 
       { 
        Schoolclass schoolclass = null; 
        while (reader.Read()) 
        { 
         schoolclass = new Schoolclass(); 
         schoolclass.SchoolclassId = Convert.ToInt32(reader["schoolclassId"]); 
         schoolclass.SchoolclassCode = reader["schoolclasscode"].ToString(); 
         schoolclasses.Add(schoolclass); 
        } 
       } 
       // Used that formerly without TransactionSCOPE => trans.Commit(); 
       return schoolclasses; 
      } 
     } 
+0

TransactionScopeは、通常、データの変更や「すべてまたは何も」の操作ではない他の操作(非db関連)を行うときに使用する必要があります。データベースからデータを選択することは、実際にはトランザクションではありません。また、これらの結果がすべて必要な場合は、1つのクエリで複数の結果セットをデータベースに取得する必要があります。あなたのケースでは、ストアドプロシージャを使用していないので、1つのクエリ(CommandText)に複数のselect文が必要です。 DataReaderには、DbDataReaderのNextResult()メソッドを使用して反復処理できる複数の結果セットがあります。 –

+0

TransactionScopeは、基礎となるADO.NETプロバイダに対して自身を知らせる(またはその逆)ため、TransactionScopeのスコープ/ライフタイム内で実行するものは自動的にトランザクションに参加します。したがって、従来の "connection.BeginTransaction()" APIよりもはるかに使いやすくなります。 –

+0

@ Shiv ok私のサンプルは、選択と少しダムだった...更新、挿入、その有効な削除。はい、私はdatareaderの.NextResult()メソッドについて知っていますが、私はそれを使用できない理由があります。最初のselectステートメントですべてのSchoolclassesを取得すると仮定します。結果セットの各schoolclassIdを2番目のselectステートメントに渡すと、各SchoolclassIdの生徒を取得できますか?私はストア手順を使用しません。私は単純なComment.Text = "テーブルからフィールドを選択" – msfanboy

答えて

1

これは正常に見える - それはTransactionScopeは、にのためにそこにあるものですコード内でトランザクション制御を提供します(これはUoWの一般的なパターンです)。

具体的なConnectionStringは、どこから分かりますか?

これはありません。それはあなたのデータアクセス層に依存し、実際にはTransactionScopeにあまり意味がありません。 TransactionScopeは、トランザクションを作成します(デフォルトでは軽量になります)。データアクセスが複数のデータベースにまたがる場合、トランザクションはに自動的にが分散トランザクションにエスカレートされます。これは、フードの下でMSDTCを使用します。

私の接続からトランザクションオブジェクトを取得し、このトランザクションオブジェクトをTransactionScopeのコンストラクタに渡す必要がありますか?

いいえ、いいえ、いいえ。上記を参照してください。今あなたがやっていることをやってください。 TransactionScopeの入れ子に害はありません。

+0

はい;いいえ。クエリを実行するために使用された接続から。いいえ。 –

+0

ok Odedですが、複数のデータベースにアクセスするのではなく、複数のテーブルを更新/削除/挿入するだけです - ここで選択するのは分かっていますが、今のところは忘れてください;-) – msfanboy

+0

@msfanboy - ポイント。 1つのデータベースで同じ方法で使用します。私の答えは...。 – Oded

関連する問題