Convert rows from a data reader into typed results

后端 未结 10 2288
醉梦人生
醉梦人生 2020-11-27 11:53

I\'m using a third party library which returns a data reader. I would like a simple way and as generic as possible to convert it into a List of objects.
For example, say

10条回答
  •  悲哀的现实
    2020-11-27 12:27

    We have implemented the following solution and feel it works pretty well. It's pretty simple and requires a bit more wiring up then what a mapper would do. However, sometimes it is nice to have the manual control and honestly, you wire up once and you're done.

    In a nutshell: Our domain models implement an interface that has a method that takes in an IDataReader and populates the model properties from it. We then use Generics and Reflection to create an instance of the model and call the Parse method on it.

    We considered using a constructor and passing IDataReader to it, but the basic performance checks we did seemed to suggest the interface was consistently faster (if only by a little). Also, the interface route provides instant feedback via compilation errors.

    One of the things I like, is that you can utilize private set for properties like Age in the example below and set them straight from the database.

    public interface IDataReaderParser
    {
        void Parse(IDataReader reader);
    }
    
    public class Foo : IDataReaderParser
    {
        public string Name { get; set; }
        public int Age { get; private set; }
    
        public void Parse(IDataReader reader)
        {
            Name = reader["Name"] as string;
            Age = Convert.ToInt32(reader["Age"]);
        }
    }
    
    public class DataLoader
    {
        public static IEnumerable GetRecords(string connectionStringName, string storedProcedureName, IEnumerable parameters = null)
                    where TEntity : IDataReaderParser, new()
        {
            using (var sqlCommand = new SqlCommand(storedProcedureName, Connections.GetSqlConnection(connectionStringName)))
            {
                using (sqlCommand.Connection)
                {
                    sqlCommand.CommandType = CommandType.StoredProcedure;
                    AssignParameters(parameters, sqlCommand);
                    sqlCommand.Connection.Open();
    
                    using (var sqlDataReader = sqlCommand.ExecuteReader())
                    {
                        while (sqlDataReader.Read())
                        {
                            //Create an instance and parse the reader to set the properties
                            var entity = new TEntity();
                            entity.Parse(sqlDataReader);
                            yield return entity;
                        }
                    }
                }
            }
        }
    }
    

    To call it, you simply provide the type parameter

    IEnumerable foos = DataLoader.GetRecords(/* params */)
    

提交回复
热议问题