0

私は、異なるテーブルからデータを取得するための複数のリポジトリがあるプロジェクトに取り組んでいます。私のリポジトリはすべて独立しており、新しいdataContextを作成し、テーブルに行を追加し、変更の送信コマンドを適用します。私のサービスでは、複数のテーブルにデータを挿入する必要がある状況がありますが、それは 1 つのトランザクションで発生するはずです。私は TrnasctionScope のものを使用してそれを達成できますが、それには同じ dataContext が必要です。StrucutreMap を使用してオブジェクトを作成しているため、同じデータ コンテキストを取得できないため、トランザクションが失敗します。

これが私のオブジェクトの様子です。

interface IConnection
{
 MyDataContext GetContext();
}

public class Connection : IConnection
{

   public MyDataContext GetContext()
   {
    return new MyDataContext();
   }

} 

interface IRepositryA
{
  int SaveDataA(objectA a);
}

public class RepositoryA : IRepositryA
{
     public int SaveDataA(objectA a)
     {
        var context = objectFactory.GetInstance<IConnection>().GetContext();   
        context.TableA.InsertOnSubmit(a);
        context.SubmitChanges();

        return a.ID;
     }
}

interface IRepositryB
{
   int SaveDataA(objectB b);
}

public class RepositoryA : IRepositryB
{
     public int SaveDataB(objectB b)
     {

        var context = objectFactory.GetInstance<IConnection>().GetContext();   
        context.TableB.InsertOnSubmit(b);
        context.SubmitChanges();
        return b.ID;
     }
}

今私のサービス層で私はそれらを

public MyServiceClass ()
 {
 public SaveAll(ObjectA a, ObjectB b)
 {

             using (TransactionScope trn);
            {
                ObjectFactory.GetInstance<IRepositryA>().SaveDataA(a);
                b.FkeyID = a.ID;
                ObjectFactory.GetInstance<IRepositryB>().SaveDataB(b);

                trn.complete();   
            }

  }
}

同じデータ コンテキストを 2 つの異なるリポジトリに渡すにはどうすればよいですか。オプションとして、以下に示すように IDataContext パラメータを受け入れる各リポジトリにオーバーロードされたメソッドを 1 つ作成していると思いました。

interface IRepositryA
{
  int SaveDataA(objectA a);
  int SaveDataA(IConnection connection, objectA a);

}

public class RepositoryA : IRepositryA
{
     public int SaveDataA(objectA a)
     {
        var connection = objectFactory.GetInstance<IConnection>();   

        return SaveData(connection, a);
     }

     public int SaveDataA(IConnection connection, objectA a)
     {
        var context = connection.GetContext();   
        context.TableA.InsertOnSubmit(a);
        context.SubmitChanges();

        return a.ID;
     }

}

interface IRepositryB
{
   int SaveDataA(objectB b);
   int SaveDataA(IConnection connection, objectB b);

}

public class RepositoryA : IRepositryB
{
     public int SaveDataB(objectB b)
     {
        var connection = objectFactory.GetInstance<IConnection>();   
        return SaveData(connection, b);
     }

     public int SaveDataA(IConnection connection, objectB b)
     {
        var context = connection.GetContext();   
        context.TableB.InsertOnSubmit(b);
        context.SubmitChanges();

        return b.ID;
     }
}

私のサービスレイヤーでは、次のように実装します

public MyServiceClass ()
 {
 public SaveAll(ObjectA a, ObjectB b)
 {
            IConnection connection= ObjectFactory.GetInstance<IConnection>();
            using (TransactionScope trn);
            {
                ObjectFactory.GetInstance<IRepositryA>().SaveDataA(connection,a);
                b.FkeyID = a.ID;
                ObjectFactory.GetInstance<IRepositryB>().SaveDataB(connection,b);

                trn.complete();   
            }

  }
}

2番目に考えたのは、GetContextメソッドを呼び出したときに同じ接続を返すようにDataContextを構成できる場合です。そのため、すべてのリポジトリが同じ接続を使用します。しかし、私はそれが常に接続を維持すると感じています. この SaveAll メソッドの実行中のみ、この接続を使用できるようにします。

あなたの助けは感謝されます。前もって感謝します。

乾杯パーミンダー

4

1 に答える 1

7

TransactionScopeは複数のDataContextで使用できますが、複数の接続が含まれるとすぐに、トランザクションはMSDTC /XA/分散トランザクションにエスカレートされます。これを機能させるには、コードを実行するシステムとデータベースサーバーの両方でMSDTCを実行する必要があります。

または、transactionscope内に明示的な接続を作成し、それをデータコンテキストに渡すと、分散トランザクションへのエスカレーションを回避できます。そうすれば、TransactionScopeは分散トランザクションにエスカレートせず、MSDTCに依存しません...

于 2009-10-20T02:17:43.487 に答える