Как я захватываю данные о SqlDataReader, которые находятся в классе в функции?

Я работаю с vb.net и в классе conexion у меня есть следующий метод:

Function consulta()

Try
    conectar()
    comando = conexion.CreateCommand()
    comando.CommandText = "select * from persona"

    reader = comando.ExecuteReader()
Catch ex As Exception
    MsgBox("Error 1 " + ex.ToString)
End Try

desconectar()

Return reader
End Function

Объект reader он типа SqlDataReader.

То, в чем я нуждаюсь, не состоит в том, чтобы вводить результаты в один DataGrid, а называть их с формуляра и показывать каждое поле в одном TextBox. Например поле nombre вводить это в один TextBox, apellido в другом TextBox.

1
задан 09.01.2017, 05:20
1 ответ

Есть 2 очень серьезные и фундаментальные проблемы в настоящем рисунке, который у тебя есть и о котором другие ответы не упомянули:

  1. Ты используешь глобальные переменные для связи и SqlDataReader.
  2. Ты закрываешь связь (desconectar()) перед тем, как возвращать SqlDataReader, так что, когда ты будешь стараться читать данные с SqlDataReader, он будет бросать в тебя исключения.

Раз вслед за разом я вижу вопросы, где использован этот главный файл использования глобальных связей. Это очень плохая практика и будет вызывать у тебя проблемы в более серьезных программах. Нет совсем не плохого в централизовании кода, который открывает связь. Но он не правилен сохранения связи в глобальной переменной.

И проблема со второй точкой - что, чтобы мочь возвращать один SqlDataReader и мочь продолжать использовать это, связь должна оставаться открытой. Но если ты снимаешь вызов desconectar() твоего метода, чтобы упорядочивать эту проблему, сейчас твой код становится еще более хрупким того, что уже, потому что не остается очень ясным, кто имеет ответственность закрытия связи.

Здесь тебя оставил гораздо более твердый и переиспользуемый главный файл, который ты можешь использовать, чтобы читать данные одного SqlDataReader для любой консультации, и что не падает в проблемы рисунка, упомянутые наверху.

Для примера, что я имею тебя, я возьму на себя ответственность, чем вместо того, чтобы иметь метод conectar() что открывает связь и распределяет ее в глобальную переменную (чтобы предотвращать), скорее я буду понимать, что ты определил метод CrearConexion что просто возвращает новую инстанцию SqlConnection не распределяя ее в переменную глобально (правильно). Немного как:

Public Function CrearConexion() As SqlConnection
    Return New SqlConnection("<cadena de conexión>")
End Function

Метод EjecutarLeerConsulta:

Public Sub EjecutarLeerConsulta(
    sql As String,
    leerRegistro As Action(Of SqlDataReader),
    ParamArray parametros As SqlParameter())

    Using conn As SqlConnection = CrearConexion()
        Using cmd = New SqlCommand(sql, conn)
            cmd.Parameters.AddRange(parametros)
            conn.Open()

            Using reader As SqlDataReader = cmd.ExecuteReader()
                While (reader.Read())
                    leerRegistro(reader)
                End While
            End Using
        End Using
    End Using
End Sub

С этим методом, ты можешь выполнять и читать любую консультацию используя лучшие практики, без глобальных переменных, не будучи должен беспокоиться, когда открытия и закрытия связи, и т.д. Всем манипулировали автоматически в этом центральном методе.

Как использовать это

Чтобы использовать метод, ты нуждаешься в том, чтобы переместить его, по крайней мере, 2 параметра:

  • Цепь SQL.
  • Выражение lambda, что определяет код, который должен работать для каждого реестра, возвращенного консультацией.
  • (Опциональный) Список параметров (SqlParameter) если консультация нуждается в них.

Пример:

EjecutarLeerConsulta(
    "select * from persona",
    Sub(reader)
        Dim nombre As String = reader("nombre")
        Dim apellido As String = reader("apellido")
        ' agrega código aquí que asigna los valores a los TextBox o lo que quieras.
    End Sub)

И если ты нуждаешься в том, чтобы вооружить консультации параметрами, вызов оказался бы таким:

EjecutarLeerConsulta(
    "select * from persona where nombre = @nombre and apellido = @apellido",
    Sub(reader)
        Dim nombre As String = reader("nombre")
        Dim apellido As String = reader("apellido")
        ' agrega código aquí que asigna los valores a los TextBox o lo que quieras.
    End Sub,
    New SqlParameter("@nombre", "John"),
    New SqlParameter("@apellido", "Smith"))
1
ответ дан 03.12.2019, 18:46

Хороший первый я рекомендую тебе добавлять в mГ©todo в конце концов тип, который ты будешь возвращать. Таким образом:

Function consulta() As SQLDataReader
End Function

, сейчас чтобы получать данные о дате reader, ты делаешь это этой формой

'Llamas a tu función para obtener el lector de datos
Dim l = consulta()
'Evaluas si tiene columnas
If l.HasRows Then
    'Evaluas si se leyerón los datos. NOTA: Esto es en caso que solo sea una
    'fila que vas a leer, si son varias te recomiendo usar While l.Read()

    If l.Read() Then
        'obtienes los datos y los agregas donde mayor te convenga

        TextBox1.Text = l["Dato1"].ToString()
        TextBox2.Text = l["Dato2"].Tostring()
        Label1.Text = l["Dato3"].ToString()
        Label2.Text = l["Dato4"].ToString()
        Dim dato5 As Integer = Integer.Parse(l["Dato5"].ToString())

        '....... etc
    End If
End If
0
ответ дан 24.11.2019, 12:18

Используй класс SQLDataReader, в c# ты можешь называть это индексом или именем колонны следующей формы

 NombreTextBox.Text = VariableDataReader["NombreColumna"].ToString();
-1
ответ дан 03.12.2019, 18:46