none
Crear consulta linq con where xx IN RRS feed

  • Pregunta

  • Hola a todos:

    Estoy iniciándome en linq y no me acaba de salir lo que necesito. Programo en vb.net.

    Tengo esta consulta en sql y lo que desearía es poderla convertir en linq. Os muestro la consulta en sql y si por favor me podéis ayudar a traducirla a linq, yá que este ejemplo me sirvirá para muchas de mis consultas.

    "SELECT  Cod_GC, Ejer_01 FROM Balances WHERE idEmpresa = @empresa AND Codigos IN ('220','310','356')" 

    No acabo de entender el where con Códigos IN como lo tendría que pasar.

    Bueno, muchas gracias a todos.

    Un saludo.

    Gemma

    viernes, 2 de septiembre de 2016 10:52

Respuestas

  • gemma_campillo,

    Puedes definir una lista para contener los valores que deseas evaluar en la cláusula where:

    Dim data = From b In Balances
                       Where New List(Of String)() From {"220", "310", "356"}.Contains(b.Codigos) _
                            And b.idEmpresa = ValorIdEmpresa
                       Select b



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta gemma_campillo viernes, 2 de septiembre de 2016 16:16
    viernes, 2 de septiembre de 2016 15:19
  • Solo una advertencia: ojo con esto, que da problemas cuando la lista es muy larga. Cuando contiene unos cuantos cientos de valores, se produce un error y no funciona correctamente.

    Si te ocurre esto, sustituye el Contains por un join, que si que funciona con muchos valores. Una vez mas, ojo con este tipo de join, que solo funciona en una direccion, es decir, no da igual hacer el join de una tabla de la BD con una lista en memoria, que hacer el join de la lista en memoria con una tabla de la BD. Ahora no recuerdo cual de las dos es la que funciona, pero si una te falla simplemente dale la vuelta y usa la otra.

    • Marcado como respuesta gemma_campillo viernes, 2 de septiembre de 2016 16:16
    viernes, 2 de septiembre de 2016 15:51
  • gemma_campillo,

    La clase SqlDataReader permite leer las filas una a una (mediante el método Read()) desde un origen de datos, los datos recuperados se basan en una consulta contenida en un objeto de tipo SqlCommand. Una consulta LinQ se ejecuta de dos maneras: de forma diferida o de forma inmediata.  La ejecución diferida se da cuando -posterior a la consulta- iteras la variable de consulta con la instrucción For Each, por otro lado, una forma de ejecución inmediata se da a través de la invocación de los métodos ToList(), ToArray(), etc.; como vez, SqlDataReader no tiene que ver con LinQ, son dos mecanismos de acceso a datos distintos. Fíjate en el siguiente ejemplo:

    'Crear una clase de ejemplo para contener marcas de vehículos
        Public Class MarcasVehiculos
    
            Property idMarca As Integer
            Property Marca As String
    
        End Class
    
        Private Sub btnConsultaLinQ_Click(sender As Object, e As EventArgs) Handles btnConsultaLinQ.Click
    
            'Definimos una lista de tipo MarcasVehiculos
            Dim Marcas As New List(Of MarcasVehiculos)()
    
            'Agregamos datos a la lista
            Marcas.Add(New MarcasVehiculos() With {.idMarca = 1, .Marca = "VOLVO"})
            Marcas.Add(New MarcasVehiculos() With {.idMarca = 2, .Marca = "SCANIA"})
            Marcas.Add(New MarcasVehiculos() With {.idMarca = 3, .Marca = "FREIGHTLINER"})
            Marcas.Add(New MarcasVehiculos() With {.idMarca = 4, .Marca = "INTERNATIONAL"})
            Marcas.Add(New MarcasVehiculos() With {.idMarca = 5, .Marca = "TOYOTA"})
    
            'Recuperamos los elementos de la lista evaluando el contenido
            Dim data = From m In Marcas
                       Where New List(Of String)() From {"VOLVO", "TOYOTA"}.Contains(m.Marca)
                       Select m
    
            'Leemos los datos (ejecución diferida)
            For Each item As MarcasVehiculos In data
                MessageBox.Show(item.Marca)
            Next
        End Sub



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta gemma_campillo viernes, 2 de septiembre de 2016 16:55
    viernes, 2 de septiembre de 2016 16:31

Todas las respuestas

  • gemma_campillo,

    Puedes definir una lista para contener los valores que deseas evaluar en la cláusula where:

    Dim data = From b In Balances
                       Where New List(Of String)() From {"220", "310", "356"}.Contains(b.Codigos) _
                            And b.idEmpresa = ValorIdEmpresa
                       Select b



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta gemma_campillo viernes, 2 de septiembre de 2016 16:16
    viernes, 2 de septiembre de 2016 15:19
  • Hola Williams:

    Muchas gracias en primer lugar, estoy empezando con linq y aparte de que encuentro poca información para vb.net, si hay mucha para c#, me está costando bastante aprenderlo, debe ser la edad, bueno te agradezco enormemente tu ayuda porque por lo menos la voy a estudiar profundamente y a ver si la entiendo bien y ese será el primer paso.

    Simplemente pedirte por favor, si con esto ya se completa y a partir de ahí ya puedo leerla con el datareader.

    Bueno, nada más, solamente agradecerte tu inestimable ayuda como siempre.

    Una abrazo.

    Gemma

    viernes, 2 de septiembre de 2016 15:41
  • Solo una advertencia: ojo con esto, que da problemas cuando la lista es muy larga. Cuando contiene unos cuantos cientos de valores, se produce un error y no funciona correctamente.

    Si te ocurre esto, sustituye el Contains por un join, que si que funciona con muchos valores. Una vez mas, ojo con este tipo de join, que solo funciona en una direccion, es decir, no da igual hacer el join de una tabla de la BD con una lista en memoria, que hacer el join de la lista en memoria con una tabla de la BD. Ahora no recuerdo cual de las dos es la que funciona, pero si una te falla simplemente dale la vuelta y usa la otra.

    • Marcado como respuesta gemma_campillo viernes, 2 de septiembre de 2016 16:16
    viernes, 2 de septiembre de 2016 15:51
  • Hola Alberto:

    Gracias por tu ayuda. El máximo número de código que tengo es una where es de 149, probaré a ver que pasa.

    Un abrazo.

    Gemma

    viernes, 2 de septiembre de 2016 16:18
  • gemma_campillo,

    La clase SqlDataReader permite leer las filas una a una (mediante el método Read()) desde un origen de datos, los datos recuperados se basan en una consulta contenida en un objeto de tipo SqlCommand. Una consulta LinQ se ejecuta de dos maneras: de forma diferida o de forma inmediata.  La ejecución diferida se da cuando -posterior a la consulta- iteras la variable de consulta con la instrucción For Each, por otro lado, una forma de ejecución inmediata se da a través de la invocación de los métodos ToList(), ToArray(), etc.; como vez, SqlDataReader no tiene que ver con LinQ, son dos mecanismos de acceso a datos distintos. Fíjate en el siguiente ejemplo:

    'Crear una clase de ejemplo para contener marcas de vehículos
        Public Class MarcasVehiculos
    
            Property idMarca As Integer
            Property Marca As String
    
        End Class
    
        Private Sub btnConsultaLinQ_Click(sender As Object, e As EventArgs) Handles btnConsultaLinQ.Click
    
            'Definimos una lista de tipo MarcasVehiculos
            Dim Marcas As New List(Of MarcasVehiculos)()
    
            'Agregamos datos a la lista
            Marcas.Add(New MarcasVehiculos() With {.idMarca = 1, .Marca = "VOLVO"})
            Marcas.Add(New MarcasVehiculos() With {.idMarca = 2, .Marca = "SCANIA"})
            Marcas.Add(New MarcasVehiculos() With {.idMarca = 3, .Marca = "FREIGHTLINER"})
            Marcas.Add(New MarcasVehiculos() With {.idMarca = 4, .Marca = "INTERNATIONAL"})
            Marcas.Add(New MarcasVehiculos() With {.idMarca = 5, .Marca = "TOYOTA"})
    
            'Recuperamos los elementos de la lista evaluando el contenido
            Dim data = From m In Marcas
                       Where New List(Of String)() From {"VOLVO", "TOYOTA"}.Contains(m.Marca)
                       Select m
    
            'Leemos los datos (ejecución diferida)
            For Each item As MarcasVehiculos In data
                MessageBox.Show(item.Marca)
            Next
        End Sub



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta gemma_campillo viernes, 2 de septiembre de 2016 16:55
    viernes, 2 de septiembre de 2016 16:31
  • Hola Williams:

    Desde luego te agradezco la paciencia y la bondad en ponerme el código que has puesto. He aprendido mucho más con tu código que lo que he leído en Internet. Es un placer las respuestas que das sumamente didácticas. Para una que nada mas ha trabajado con los stores procedures, todo esto de linq, entity framework, le suena a música celestial, pero en este caso me veo obligada a aprenderlo y entenderlo ya que se me van a multiplicar las select y updates de una forma importante.

    Bueno, solo me queda volverte a agradecer tu generosa disposición a ayudarme como siempre.

    Recibe un fuerte abrazo querido Williams.

    Gemma

    viernes, 2 de septiembre de 2016 16:55