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 I have a class 'Employee' with 2 properties EmployeeId and Name, I would like the data reader (which contains a list of employees) to be converted into List< Employee>.
I guess I have no choice but to iterate though the rows of the data reader and for each of them convert them into an Employee object that I will add to the List. Any better solution? I'm using C# 3.5 and ideally I would like it to be as generic as possible so that it works with any classes (the field names in the DataReader match the property names of the various objects).
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
- How to know full paths to DLL's from .csproj f
A stupidly performant option, should you not mind an external dependency (the amazing
Fast Member
nuget package):To use:
For .NET Core 2.0:
Here is an extension method that works with .NET CORE 2.0 to execute RAW SQL and map results to LIST of arbitrary types:
USAGE:
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 theParse
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 likeAge
in the example below and set them straight from the database.To call it, you simply provide the type parameter
Do you really need a list, or would IEnumerable be good enough?
I know you want it to be generic, but a much more common pattern is to have a static Factory method on the target object type that accepts a datarow (or IDataRecord). That would look something like this:
.
Then if you really need a list rather than an IEnumerable you can call
.ToList()
on the results. I suppose you could also use generics + a delegate to make the code for this pattern more re-usable as well.Update: I saw this again today and felt like writing the generic code:
You could build an extension method like:
and use it like:
Joel's suggestion is a good one. You can choose to return
IEnumerable<T>
. It's easy to transform the above code:If you want to automatically map the columns to properties, the code idea is the same. You can just replace the
generator
function in the above code with a function that interrogatestypeof(T)
and sets the properties on the object using reflection by reading the matched column. However, I personally prefer defining a factory method (like the one mentioned in Joel's answer) and passing a delegate of it into this function:Whilst I wouldn't recommend this for production code, but you can do this automatically using reflection and generics:
You can then use
CreateRecord<T>()
to instantiate any class from the fields in a data reader.