SQL ExecuteReader 질문 드려요!

안녕하세요, sql 데이터 읽어오는 ExecuteReader 관련해서 질문드립니다.

public async Task<DataTable> ExecuteReaderAsync(string query, params MySqlParameter[] parameters)
        {
            var dataTable = new DataTable();

            using (var connection = new MySqlConnection(ConnectionString))
            {
                using (var command = new MySqlCommand(query, connection))
                {
                    await connection.OpenAsync();

                    if (parameters != null)
                    {
                        command.Parameters.AddRange(parameters);
                    }


                    using (var reader = await command.ExecuteReaderAsync())
                    {
                        dataTable.Load(reader);
                    }
                }
            }

            return dataTable;
        }

위 코드는 쿼리로 실행 된 데이터를 dataTable 에 담게끔 하는건데요.
reader ← 변수에는 데이터가 정상적으로 다 들어가 있는데,
dataTable.Load(reader); <= 여기에서 데이터테이블에 담기만 하면 전체 데이터가 담기지가 않습니다.

예를 들어 select 쿼리를 실행해서 reader 변수에 총 3개 행의 데이터가 담겨져 있는데,
dataTable.Load(reader); ← 이 코드를 통해서 데이터 테이블에 담기면 가장 마지막 행 1개만 담깁니다…

어떤 문제 인지 감이 잡히지가 않습니다…
왜 그런지 혹시 아시는분 답변 해주시면 감사하겠습니다!

    public async Task<DataTable> ExecuteReaderV2Async(string query, params MySqlParameter[] parameters)
        {
            var dataTable = new DataTable();
            using (var connection = new MySqlConnection(ConnectionString))
            {
                using (var command = new MySqlCommand(query, connection))
                {
                    await connection.OpenAsync();
                    if (parameters != null)
                    {
                        command.Parameters.AddRange(parameters);
                    }

                    using (var reader = await command.ExecuteReaderAsync())
                    {
                        // 데이터 테이블의 구조를 설정
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            dataTable.Columns.Add(reader.GetName(i), reader.GetFieldType(i));
                        }

                        // 수동으로 행 추가
                        while (await reader.ReadAsync())
                        {
                            var row = dataTable.NewRow();
                            for (int i = 0; i < reader.FieldCount; i++)
                            {
                                row[i] = reader.IsDBNull(i) ? DBNull.Value : reader.GetValue(i);
                            }
                            dataTable.Rows.Add(row);
                        }
                    }
                }
            }
            return dataTable;
        }

위와 같이 reader 에 있는 값을 for문 돌려서 dataTable 에 하나씩 넣으면, 정상적으로 모든 데이터가 들어가네요… 그런데 왜 dataTable.Load(reader); 에는 데이터가 다 들어가지가 않는지 원…

DataTable에 데이터를 넣는게 목적이면 SqlDataAdapter를 사용하시는게 더 편할텐데요.

1 Like

저도 크게 모르지만 …
datareader 는 기본적으로 row단위의 데이터 작업을 위해 만들어진 것으로 압니다.
그래서 row단위 작업의 편리함. 경량화로 인한 속도의 장점으로 그 외에는 추천 드리지 않습니다.

위 내용 대로면 당연히 직렬화가 안되어 가장 마지막 데이터가 들어가는 것 같습니다.
기본 사용법과 같이 while 작업을 권장 합니다.

그 외 db connection을 독점한다는 문제는 이전에도 문제였지만, 비동기가 대두된 후 작업이 묶이는 몇 가지 조건이 경우가 보이더군요.
이미 해결하신 내용대로 윗분 말씀대로 SqlDataAdapter 또는 while로 이용하시는게 좋을것 같습니다.

1 Like

감사합니다!! 기존에 이렇게 쓰고 있던 코드라서요, 나중에 기회 되면 SqlDataAdapter 써보겠습니다!!

답변 감사드려요!!

헐 그렇군요.
이유가 있을 거라 생각했는데. 그냥 누가 만들어둔 코드라서 ㅠㅠ.