2011-11-26 6 views
8

こんにちは、Entity Frameworkと一緒にトランザクションを使用しようとしています。トランザクションを実装するためにさまざまな方法でオンラインで利用可能な多くの情報があるため、正しい方法で少し混乱していると言わざるを得ない。私はEmployeeとCompanyの2つのテーブルを持つサンプルデータベースを持っています。 Employeeテーブルには、会社IDを参照する外部キーがあります。 Companyテーブルにレコードを挿入し、次にEmployeeテーブルにレコードを挿入するトランザクションを実装する場合、レコードが挿入されるようにレコードを挿入するには、次のコードが必要です。Entity Frameworkでのトランザクションの理解

public void addCompanyToDatabase() 
    { 
     using (var context = new myTestEntities()) 
     { 
      context.Connection.Open(); //added this as was getting the underlying 
      //provider failed to open 
      using (TransactionScope scope = new TransactionScope()) 
      { 
       try 
       { 
        Company c = new Company(); 
        c.Name = "xyz"; 
        context.Companies.AddObject(c); 
        context.SaveChanges(); 

        //int a = 0; 
        //int b = 5/a; 

        Employee e = new Employee(); 
        e.Age = 15; 
        e.Name = "James"; 
        e.CompanyId = c.Id; 
        context.Employees.AddObject(e); 
        context.SaveChanges(); 

        scope.Complete(); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine("Exception Occurred"); 
       } 
      } 
     } 
    } 

これがトランザクションを実装する正しい方法であるかどうかを知りたいと思っていました。その場合は、SaveChanges(false)scope.AcceptAllChanges()の機能の使用は何ですか。どんな情報でも役立ちます。

答えて

14

接続やトランザクションを管理する必要はありません。Entity Frameworkがこれを行います。 EFに開かれた接続(ただし接続文字列)を指定しないと、context.SaveChanges()への呼び出し中に接続が開始され、トランザクションが開始されます。その呼び出し中に何かが失敗すると、トランザクションはロールバックされます。言い換えれば

、あなたの方法は、単純に次のようになります

public void addCompanyToDatabase() 
{ 
    using (var context = new myTestEntities()) 
    { 
     Company c = new Company(); 
     c.Name = "xyz"; 
     context.Companies.AddObject(c); 

     Employee e = new Employee(); 
     e.Age = 15; 
     e.Name = "James"; 
     e.CompanyId = c.Id; 
     context.Employees.AddObject(e); 

     // Only call SaveChanges last. 
     context.SaveChanges(); 
    } 
} 
+0

私の例の場合は意味があります。あなたは私がトランザクションを必要とする例を私に与えることができますか?上記のコードがトランザクションを実装する方法だとしたら?私は2つの異なるコンテキストでレコードを更新するのが一つのシナリオだと思います。 – nighthawk457

+1

トランザクションが必要な最も一般的なケースは、 'SaveChanges'を複数回呼び出す必要があるときです。これは、新しいオブジェクトの(データベース生成された)IDが必要な場合、またはORMに特定の順序で操作を実行させる必要がある場合に発生します(たとえば、LINQ to SQLは挿入後に削除を並べ替える傾向がありますが、データベース制約の例外)。 – Steven

+3

すべての場合、 'TransactionScope'を使用する必要はまだありません。 'TransactionScope'が必要な場合は、複数のデータベースに渡ってアトミックな操作が必要なため、おそらくシステムに設計上の欠陥があります。純粋に私の自動化された統合テストのために 'TransactionScope'を使用します。 TransactionScopeで呼び出しコードをラップするだけで、すべての(データベース)変更がテストの最後にロールバックされていることを確認できます。コードを変更する必要はありません。 – Steven

0

1-このサービスは(私はトランザクションサービスを考える)のTransactionScope

2をサポートするために、クライアントに実行でなければなりませんのトウ以上のデータベースがアプリケーションにあり、すべてのデータベースをトランザクションで更新したい場合(たとえば、コンテキストの接続文字列を変更するなど)。

3 - データベースを使用している場合は、内部的にトランザクションを実装するSaveChanges()を使用する方が適しています。

関連する問題