如何将 SqlDataReader 结果转换为通用列表 List<T>

How to convert SqlDataReader result to generic list List<T>

我正在尝试使用 Ado.net 从 Azure 数据库中获取记录 我为此使用了 SqlDataReader class。虽然取数据成功了,但我不知道如何将其转换为通用列表。

protected List<T> GetList<T>()
        {
            try
            {
                using (var query = ExecuteReader())
                {
                         // What Goes Here ?
                }

            }
            finally
            {
                if (_sqlCommand.Connection.State == ConnectionState.Open)
                {
                    _sqlCommand.Connection.Close();
                }
            }
        }

ExecuteReader 方法,

protected SqlDataReader ExecuteReader()
        {
            if (_sqlCommand.Connection.State != ConnectionState.Open)
            {
                _sqlCommand.Connection.Open();
            }

            return _sqlCommand.ExecuteReader();
        }

数据模型,

public class Student
    {
        [EntityKey]
        public int StudentId { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Major { get; set; }

    }

注意: 我想知道是否还有其他简单的方法

while (query.Read())
{
  Console.WriteLine($"First column {query[0]}");
  Console.WriteLine($"Named column {query["put a columnname here"]}");
}

Read() 将为您提供第一行和下一行。

SqlDataReader 不是容器,它是用于加载数据的游标。它不能转换为任何容器类型。应用程序代码必须使用它来加载结果,然后构造对象并将它们放入列表中。这在 ADO.NET 文档中有描述,例如 Retrieving data using a DataReader:

    var list=new List<Student>();
    if (reader.HasRows)
    {
        while (reader.Read())
        {
            var student=new Student();
            student.Id=reader.GetInt32(0);
            student.Name = reader.GetString(1));
            ...
        }
    }
    else
    {
        Console.WriteLine("No rows found.");
    }

这是很多样板文件,这就是为什么像 Entity Framework 或 micro-ORMs 这样的 ORM 像 Dapper 用于执行查询并将结果映射到对象的原因。

使用 Dapper,所有这些代码都可以替换为:

var sql="Select * from Students where Major=@major";
var students=connection.Query<Student>(sql,new {major="Computer Science"});

Dapper 将使用 @major 参数创建参数化查询,执行它,根据结果构建 Student 个对象,并将它们 return 作为 IEnumerable<Student>。它甚至负责打开和处理连接。

Dapper 通过使用反射来识别类型的属性,使用它们的名称加载正确的字段并将它们分配给它创建的对象。

var dt=new DataTable();
dt.Load(myDataReader);
list<DataRow> dr=dt.AsEnumerable().ToList();

 public DataReaderToListModel()  
        {  
            StudentList = new ObservableCollection<StudentModel>();  
            LoadData();  
        }  
public ObservableCollection<StudentModel> StudentList { get; set; }
 #region Varible declarations  
        private SqlConnection _sqlConnection;  
        private SqlCommand _sqlCommand;  
        private SqlDataReader _sqlDataReader;  
        private string _strsqlcommand;   
 #endregion 
  #region Method for Getting the data from Database  
        public void LoadData()  
        {  
            try  
            {  
            // Connection Strings 
            // Connecting to DB 
             _sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConString"].ConnectionString);  
                if (_sqlConnection.State != ConnectionState.Open)  
                    _sqlConnection.Open();  
                _strsqlcommand = "Your Query";
                _sqlDataReader = _sqlCommand.ExecuteReader();  
                var studentmodellist = new ObservableCollection<StudentModel>();  
  
                while (_sqlDataReader.Read())  
                {  
                    var studentModel = new StudentModel  
                    {  
                        StudentId  = _sqlDataReader.GetInt32(_sqlDataReader.GetOrdinal("StudentId ")),  
                        Name= _sqlDataReader.GetString(_sqlDataReader.GetOrdinal("Name")),  
                        Age= _sqlDataReader.GetInt32(_sqlDataReader.GetOrdinal("Age")),  
                        Major = _sqlDataReader.GetString(_sqlDataReader.GetOrdinal("Major"))  
                    };  
                    studentmodellist.Add(studentModel);  
                }  
  
                StudentList = studentmodellist;  
                _sqlConnection.Close();  
            }  
            catch (Exception exception)  
            {  
                MessageBox.Show("DataLoading Failed beacause of following  Reason \n" + exception.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);  
            }  
        }   
        #endregion  

更多信息请参考SO Thread