none
problema Linq to sql y System.Transactions.TransactionScope RRS feed

  • Pregunta

  • Hola, buenos dias

    tengo un problema con Linq to sql dentro de transacciones

    Quiero buscar un valor de un campo en una tabla. Si no encuentra ningun registro se produce un error cuando llega a la linea 

    If WMaxOrden.Count <> 0 Then

    Pero esto sucede solo cuando esta dentro de una transaccion. Si saco la transaccion funciona, si tengo registros en la tabla LogTransacciones tambien funciona.

    Alguien me puede dar una mano y decirme como deberia preguntar si tengo registros o de alguna forma de solucionarlo?

     

    Using scope = New System.Transactions.TransactionScope()

        Dim WMaxOrden = From O In WTablasGeneralDataContext.LogTransacciones _
                        Where O.Empresa = XEmpresa And _
                              O.FechaIngreso = XFechaActual _
                        Order By O.Orden Descending _
                        Select O
        If WMaxOrden.Count <> 0 Then
          WOrden = WMaxOrden.FirstOrDefault.Orden + 1

        Else

         WOrden = 0

        End If

    ...

    ...

    ...

    End Using

     

     

    El error es el siguiente

    http://img686.imageshack.us/img686/7413/dibujoece.jpg

     

    miércoles, 1 de diciembre de 2010 16:23

Respuestas

  • Intenta con .FirstOrDefault(), lo cual será más rápido que el .ToList(), suponiendo que sólo necesitas saber si existen o no registros y obtener sólo el primero que cumpla con el where.

    Dim WMaxOrden = (From O In ...
                        Select O).FirstOrDefault()

    If WMaxOrden Is Not Nothing Then
          WOrden = WMaxOrden.Orden + 1

        Else

         WOrden = 0

    End If

    Por otro lado, el error se produce porque estás utilizando una transacción distribuible explícita lo cual implica que el servidor esté corriendo el servicio de DTC. Este tipo de transacciones sólo son necesarias si las transacciones afectan a sistemas externos o se trata de un entorno multi-servidor, así que calculo que no necesitas este tipo de transacción (el utilizado por la clase TransactionScope).

    Ten en cuenta que en LINQ hay 3 formas diferentes de implementar transacciones:

     

     Espero que te sea útil.

    Mas información en: http://thepiratblog.blogspot.com/2010/09/presentacion-de-curso-introduccion-linq.html

    Suerte !

    Federico Colombo

    http://thepiratblog.blogspot.com
     

     

    martes, 8 de febrero de 2011 6:38

Todas las respuestas

  • :-)
    Hola,

    Podría ser un problema de concurrencia (un deadlock). Por otro lado porque no pruebas a:

     Dim WMaxOrden = (From O In WTablasGeneralDataContext.LogTransacciones _
                        Where O.Empresa = XEmpresa And _
                              O.FechaIngreso = XFechaActual _
                        Order By O.Orden Descending _
                        Select O).ToList()

    Es decir, en lugar de usar una consulta LINQ que devuelve un IQueryable<T>, forzar a que devuelva un List<T>. Por otro lado, no veo que estés haciendo nada que requiera el uso de una transacción... ¿seguro que es necesario usarla?

    Saludos,


    No olvides marcar la respuesta como correcta si te ha sido de utilidad :-)

    [MS-MVP-MCTS]

    Follow me on Facebook or Twitter!

    Mi Perfil MVP en: https://mvp.support.microsoft.com/profile/Lluis
    NUG: http://andorradotnet.com
    Web: http://www.ordeeno.com
    Geeks: http://geeks.ms/blogs/lfranco

    miércoles, 1 de diciembre de 2010 16:42
    Moderador
  • con el toList me pasa lo mismo

    tengo mas codigo el cual hace varios insert en diferentes tablas por eso coloque los tres puntos (...) y por eso uso la transaccion pero tengo ese error

    miércoles, 1 de diciembre de 2010 17:30
  • Intenta con .FirstOrDefault(), lo cual será más rápido que el .ToList(), suponiendo que sólo necesitas saber si existen o no registros y obtener sólo el primero que cumpla con el where.

    Dim WMaxOrden = (From O In ...
                        Select O).FirstOrDefault()

    If WMaxOrden Is Not Nothing Then
          WOrden = WMaxOrden.Orden + 1

        Else

         WOrden = 0

    End If

    Suerte !

    Federico Colombo

    http://thepiratblog.blogspot.com
     

     

    martes, 8 de febrero de 2011 6:28
  • Intenta con .FirstOrDefault(), lo cual será más rápido que el .ToList(), suponiendo que sólo necesitas saber si existen o no registros y obtener sólo el primero que cumpla con el where.

    Dim WMaxOrden = (From O In ...
                        Select O).FirstOrDefault()

    If WMaxOrden Is Not Nothing Then
          WOrden = WMaxOrden.Orden + 1

        Else

         WOrden = 0

    End If

    Por otro lado, el error se produce porque estás utilizando una transacción distribuible explícita lo cual implica que el servidor esté corriendo el servicio de DTC. Este tipo de transacciones sólo son necesarias si las transacciones afectan a sistemas externos o se trata de un entorno multi-servidor, así que calculo que no necesitas este tipo de transacción (el utilizado por la clase TransactionScope).

    Ten en cuenta que en LINQ hay 3 formas diferentes de implementar transacciones:

     

     Espero que te sea útil.

    Mas información en: http://thepiratblog.blogspot.com/2010/09/presentacion-de-curso-introduccion-linq.html

    Suerte !

    Federico Colombo

    http://thepiratblog.blogspot.com
     

     

    martes, 8 de febrero de 2011 6:38