none
transacciones en LINQ RRS feed

  • Pregunta

  • Hola buen dia.

    Tengo una aplicación que estoy intentando pasa el acceso a datos a LINQto SQl , actualmente hago mis consultas directas a SQl 2005 con DataTables y DataSets, dentro de mi aplicación tengo una funcion que inserta datos a la BD en dos tablas, en una inserto los encabezados y en otra detalles(puede o no tener), para esto uso lo sig:

    public void insOficiosIn(DataTable dtEncabezado, DataTable dtDetalles, ref string strSqlErr, ref int intRetVal, ref string strNewFolio)

    {

          strCon.Open();

          SqlTransaction Trans = strCon.BeginTransaction();

          SqlCommand Comd = new SqlCommand();

          //Inciamos transacción

          Comd.Transaction = Trans;

          try

          {

                Comd.CommandText = "Proc_Encabezado";

                Comd.Connection = strCon;

                Comd.CommandType = CommandType.StoredProcedure;

                Comd.Parameters.Add("@Return_Value", SqlDbType.Int);

                Comd.Parameters["@Return_Value"].Direction = ParameterDirection.ReturnValue;

                Comd.Parameters.Add("@Clave", SqlDbType.Int);

                Comd.Parameters.Add("@Descripcion", SqlDbType.VarChar, 15);

                //Creación de todos los demas parametros

                Comd.Parameters["@Clave"].Value = dtEncabezado.Rows[0].ItemArray[0];

                Comd.Parameters["@Descripcion "].Value = dtEncabezado.Rows[0].ItemArray[1];

                //Asignación de valores de todos los demas parametros

                Comd.ExecuteNonQuery();

                intRetVal = Convert.ToInt32(Comd.Parameters["@Return_Value"].Value.ToString());

                strNewFolio = Comd.Parameters["@Ret_Folio"].Value.ToString();

                if (intRetVal != 0)

                      Trans.Rollback();//Ocurrio un error, no hace nada

                else

                { //Insertar los detalles.

                      foreach (DataRow dtr in dtDetalles.Rows)

                      {

                            Comd.CommandText = "Proc_Detalles";

                            Comd.Connection = strCon;

                            Comd.CommandType = CommandType.StoredProcedure;

                            Comd.Parameters.Clear();

                            Comd.Parameters.Add("@Return_Value", SqlDbType.Int);

                            Comd.Parameters["@Return_Value"].Direction = ParameterDirection.ReturnValue;

                           Comd.Parameters.Add("@ClaveEncabezado", SqlDbType.Int);

                            Comd.Parameters.Add("@ClaveDetalle", SqlDbType.Int);

                            Comd.Parameters.Add("@DescripcionDetalle",

    SqlDbType.VarChar, 15);

                            //Creación de todos los demas parametros

                            Comd.Parameters["@ClaveEncabezado "].Value = strNewFolio;

                            Comd.Parameters["@ClaveDetalle "].Value = Convert.ToInt32(dtr[0]);

                            Comd.Parameters["@DescripcionDetalle "].Value = dtr[0].ToString();

                            //Asignación de valores de todos los demas parametros

                            Comd.ExecuteNonQuery();

                            intRetVal = Convert.ToInt32(Comd.Parameters["@Return_Value"].Value.ToString());

                            if (intRetVal != 0)

                                break; //Ocurrio un error.

                        }

                        if (intRetVal != 0)

                            Trans.Rollback();//Ocurrio un error, no hace nada

                        else

                            Trans.Commit();//Aplicamos la transacción

                    }

                }

                catch (Exception error)

                {

                    strSqlErr = error.Message;

                    intRetVal = -88888;

                    strNewFolio = "0";

                }

                finally

                {

                    strCon.Close();

                }

          }

    Ahora, todo esto lo quiero hacer en LINQ, es eso posible???

     

    saludos y gracias por sus comentarios

     

     

    jueves, 27 de enero de 2011 19:47

Respuestas

  • Hola Javier,

    LINQ to SQL por defecto trabaja utilizando transacciones, te pongo tu mismo ejemplo:

    foreach(var item in list)

    {

      llamamos al procedimiento

    }

    Context.SummitChanges();

    Todas las operaciones que se realizan en el foreach, nuevas entidades, llamadas a procedimientos, etc, no se ejecutan en el SQL Server hasta que haces el SummitChanges del SQL Server.

     


    Alberto Diaz Martin twitter://@adiazcan | http://geeks.ms/blogs/adiazmartin | MVP SharePoint Server
    • Marcado como respuesta javierTR jueves, 27 de enero de 2011 21:43
    jueves, 27 de enero de 2011 21:31
  • No, si no ejecutas el SummitChanges no tienes el valor del procedimiento, si no quieres dejar de utililizar los procedimientos y pasar a un modelo mas desacoplado de la base de datos, una solución es usar System.Transaction que te permite controlar las transacciones de LINQ desde el código .NET


    Alberto Diaz Martin twitter://@adiazcan | http://geeks.ms/blogs/adiazmartin | MVP SharePoint Server
    • Marcado como respuesta javierTR jueves, 27 de enero de 2011 21:43
    jueves, 27 de enero de 2011 21:42

Todas las respuestas

  • Hola Javier,

    LINQ to SQL por defecto trabaja utilizando transacciones, te pongo tu mismo ejemplo:

    foreach(var item in list)

    {

      llamamos al procedimiento

    }

    Context.SummitChanges();

    Todas las operaciones que se realizan en el foreach, nuevas entidades, llamadas a procedimientos, etc, no se ejecutan en el SQL Server hasta que haces el SummitChanges del SQL Server.

     


    Alberto Diaz Martin twitter://@adiazcan | http://geeks.ms/blogs/adiazmartin | MVP SharePoint Server
    • Marcado como respuesta javierTR jueves, 27 de enero de 2011 21:43
    jueves, 27 de enero de 2011 21:31
  • Gracias por tu respuesta Alberto.

    El detalle es el siguiente, mi stored procedure 1 genera una nueva clave la cual debo tomar para insertarla en el sotored procedure 2. Puedo tomar ese valor del SP1 que lo retorno con un parametro del tipo Output y usarlo en el SP2?

    Ese parametro tipo Output ya tiene valor antes de ejecutar el Context.SummitChanges(); ???

    Gracias

     

     

    jueves, 27 de enero de 2011 21:39
  • No, si no ejecutas el SummitChanges no tienes el valor del procedimiento, si no quieres dejar de utililizar los procedimientos y pasar a un modelo mas desacoplado de la base de datos, una solución es usar System.Transaction que te permite controlar las transacciones de LINQ desde el código .NET


    Alberto Diaz Martin twitter://@adiazcan | http://geeks.ms/blogs/adiazmartin | MVP SharePoint Server
    • Marcado como respuesta javierTR jueves, 27 de enero de 2011 21:43
    jueves, 27 de enero de 2011 21:42
  • Perfecto.

     

    Gracias Alberto, te agradesco mucho

     

     

    jueves, 27 de enero de 2011 21:43