2011-11-26 12 views
8

Hola, estoy tratando de usar transacciones junto con Entity Framework. Con tanta información disponible en línea sobre las diferentes formas de implementar transacciones, debo decir que estoy un poco confundido en el camino correcto. Tengo una base de datos de ejemplo con dos tablas Employee and Company. La tabla Empleado tiene una clave externa que hace referencia al Id de la empresa. Teniendo en cuenta que quiero implementar una transacción en la que inserte un registro en la tabla Company y luego un registro en la tabla Empleado y deseo hacer esto para que los registros se inserten solo si ambos tienen éxito, tengo el siguiente código.Descripción de las transacciones en 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"); 
       } 
      } 
     } 
    } 

Quería saber si esta era la forma correcta de implementar las transacciones. Si es así, ¿cuál es el uso de las funciones SaveChanges(false) y scope.AcceptAllChanges()? Cualquier información sería de gran ayuda.

Respuesta

14

En su caso, no necesita administrar ninguna conexión o transacción: Entity Framework lo hará por usted. Cuando no suministra EF con una conexión abierta (pero con una cadena de conexión), se abrirá una conexión e iniciará una transacción durante la llamada al context.SaveChanges(). Cuando algo falla durante esa llamada, la transacción se revertirá.

En otras palabras, el método puede ser similar a esto:

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

Eso tiene sentido en el caso de mi ejemplo. Sin embargo, ¿podría darme un ejemplo en el que necesitaría una transacción? y si el código que mencioné anteriormente es el camino a seguir para implementar una transacción? Supongo que actualizar los registros con dos contextos diferentes es un escenario. – nighthawk457

+1

El caso más común que he encontrado que hace que necesite una transacción, es cuando necesita llamar 'SaveChanges' varias veces. Esto puede suceder cuando necesita el ID (generado en la base de datos) de un nuevo objeto, o cuando necesita obligar al ORM a ejecutar operaciones en un orden determinado (por ejemplo, LINQ to SQL tiende a reordenar las eliminaciones después de las inserciones, pero esto puede desencadenar una excepción de restricción de base de datos). – Steven

+3

En todos los casos, aún no es necesario usar 'TransactionScope'. Si necesita un 'TransactionScope' porque necesita que las operaciones sean atómicas en una base de datos múltiple, es probable que tenga un defecto de diseño en su sistema. Yo uso 'TransactionScope's puramente para mis pruebas de integración automatizadas. Simplemente rastree el código de llamada en un 'TransactionScope' y puede asegurarse de que todos los cambios (de la base de datos) se retrotraigan al final de la prueba, sin tener que alterar ningún código para esto. – Steven

0

1-este servicio (creo servicio de transacciones) debe ser plazo en el cliente para apoyar TransactionScope

2 -Utilice cuando tenga remolque o más bases de datos en su aplicación y desea que todas las bases de datos se actualicen transaccionalmente (como cambiar la cadena de conexión de su contexto).

3-Cuando tenga una base de datos es mejor utilizar SaveChanges() que implemente la transacción internamente.

Cuestiones relacionadas