Fastest way to map result of SqlDataReader to object
When in doubt regarding anything db or reflection, I ask myself, "what would Marc Gravell do?".
In this case, he would use FastMember! And you should too. It's the underpinning to the data conversions in Dapper, and can easily be used to map your own DataReader to an object (should you not want to use Dapper).
Below is an extension method converting a SqlDataReader
into something of type T
:
PLEASE NOTE: This code implies a dependency on FastMember and is written for .NET Core (though could easily be converted to .NET Framework/Standard compliant code).
public static T ConvertToObject<T>(this SqlDataReader rd) where T : class, new()
{
Type type = typeof(T);
var accessor = TypeAccessor.Create(type);
var members = accessor.GetMembers();
var t = new T();
for (int i = 0; i < rd.FieldCount; i++)
{
if (!rd.IsDBNull(i))
{
string fieldName = rd.GetName(i);
if (members.Any(m => string.Equals(m.Name, fieldName, StringComparison.OrdinalIgnoreCase)))
{
accessor[t, fieldName] = rd.GetValue(i);
}
}
}
return t;
}
The most upvoted answer mentions @MarkGravel and his FastMember. But if you're already using Dapper, which is also a component of his, you can use Dapper's GetRowParser
like this:
var parser = reader.GetRowParser<MyObject>(typeof(MyObject));
while (reader.Read())
{
var myObject = parser(reader);
}