2011-11-26 16 views
8

Ciao Sto cercando di utilizzare le transazioni insieme a Entity Framework. Con così tante informazioni disponibili online sui diversi modi di implementare le transazioni, devo dire che sono un po 'confuso nel modo giusto. Ho un database di esempio con due tabelle Employee and Company. La tabella Dipendente ha una chiave esterna che si riferisce all'ID aziendale. Considerando che voglio implementare una transazione in cui inserisco un record nella tabella Società e quindi un record nella tabella Employee e voglio farlo in modo che i record vengano inseriti solo se entrambi hanno esito positivo, ho il seguente codice.Informazioni sulle transazioni in 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"); 
       } 
      } 
     } 
    } 

Volevo sapere se questo era il modo giusto di implementare le transazioni. In questo caso, a cosa servono le funzioni SaveChanges(false) e scope.AcceptAllChanges(). Qualsiasi informazione sarebbe utile.

risposta

14

Nel tuo caso non è necessario gestire alcuna connessione o transazione: Entity Framework lo farà per te. Quando non si fornisce EF con una connessione aperta (ma con una stringa di connessione), si aprirà una connessione e si avvierà una transazione durante la chiamata a context.SaveChanges(). Quando qualcosa non funziona durante la chiamata, la transazione verrà ripristinata.

In altre parole, il metodo può semplicemente apparire come segue:

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

Questo ha senso nel caso del mio esempio. Puoi darmi un esempio in cui avrei bisogno di una transazione? e se il codice che ho menzionato sopra è la strada da percorrere per implementare una transazione? Immagino che aggiornare i record con due contesti diversi sia uno scenario. – nighthawk457

+1

Il caso più comune che ho riscontrato che richiede una transazione, è quando è necessario chiamare 'SaveChanges' più volte. Ciò può accadere quando è necessario l'id (generato da un database) di un nuovo oggetto o quando è necessario forzare l'ORM per eseguire le operazioni in un determinato ordine (ad esempio, LINQ su SQL tende a riordinare le eliminazioni dopo gli inserimenti, ma ciò potrebbe un'eccezione di vincolo del database). – Steven

+3

In tutti i casi, non è ancora necessario utilizzare un 'TransactionScope'. Se hai bisogno di un 'TransactionScope' perché hai bisogno che le operazioni siano atomiche su più database, probabilmente hai un difetto di progettazione nel tuo sistema. Io uso 'TransactionScope's esclusivamente per i miei test di integrazione automatica. Basta eseguire il rap del codice chiamante in un 'TransactionScope' e si può essere sicuri che tutte le modifiche (del database) vengano ripristinate alla fine del test, senza dover modificare alcun codice per questo. – Steven

0

1-questo servizio (credo servizio di transazione) deve essere run client per sostenere TransactionScope

2 -Utilizzare quando si dispone di o più database nell'applicazione e si desidera aggiornare tutti i database transazionali (ad esempio modificare la stringa di connessione del contesto).

3-Quando si dispone di un database, utilizzare SaveChanges() che implementa internamente la transazione.

Problemi correlati