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); 에는 데이터가 다 들어가지가 않는지 원…

1개의 좋아요

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

3개의 좋아요

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

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

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

1개의 좋아요

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

1개의 좋아요

답변 감사드려요!!

1개의 좋아요

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

1개의 좋아요