This question already has an answer here:
I have data in a DataReader
which I want to be converted to a List<T>
.
What is a possible simple solution for this?
For e.g. in CustomerEntity class, I have CustomerId and CustomerName properties.If my DataReader returns these two columns as data, then how can I convert it into List<CustomerEntity>
.
I have seen systems that use Reflection and attributes on Properties or fields to maps DataReaders to objects. (A bit like what LinqToSql does.) They save a bit of typing and may reduce the number of errors when coding for DBNull etc. Once you cache the generated code they can be faster then most hand written code as well, so do consider the “high road” if you are doing this a lot.
See "A Defense of Reflection in .NET" for one example of this.
You can then write code like
...
(AutoMap(), is an extension method)
@Stilgar, thanks for a great comment
If are able to you are likely to be better of using NHibernate, EF or Linq to Sql, etc However on old project (or for other (sometimes valid) reasons, e.g. “not invented here”, “love of stored procs” etc) It is not always possible to use a ORM, so a lighter weight system can be useful to have “up your sleeves”
If you every needed too write lots of IDataReader loops, you will see the benefit of reducing the coding (and errors) without having to change the architecture of the system you are working on. That is not to say it’s a good architecture to start with..
I am assuming that CustomerDTO will not get out of the data access layer and composite objects etc will be built up by the data access layer using the DTO objects.
I would suggest writing an extension method for this:
You can then use LINQ's
ToList()
method to convert that into aList<T>
if you want, like this:I would actually suggest putting a
FromDataReader
method inCustomer
(or somewhere else):That would leave:
(I don't think type inference would work in this case, but I could be wrong...)
Obviously
@Ian Ringrose
's central thesis that you should be using a library for this is the best single answer here (hence a +1), but for minimal throwaway or demo code here's a concrete illustration of@SLaks
's subtle comment on@Jon Skeet
's more granular (+1'd) answer:As in
@Jon Skeet
's answer, thebit can be extracted into a helper (I like to dump them in the query class):
and used as:
UPDATE Mar 9 13: See also Some excellent further subtle coding techniques to split out the boilerplate in this answer
The simplest Solution :
I would (and have) started to use Dapper. To use your example would be like (written from memory):
CreateConnection()
would handle accessing your db and returning a connection.Dapper handles mapping datafields to properties automatically. It also supports multiple types and result sets and is very fast.
Query returns
IEnumerable
hence theToList()
.I've covered this in a pet project.. use what you want.
Note that the ListEx implements the IDataReader interface.
Or use object mapping like in the following example.
Have a look at http://caprisoft.codeplex.com