Click here to Skip to main content
12,404,895 members (65,894 online)
Click here to Skip to main content
Add your own
alternative version

Stats

14.3K views
6 bookmarked
Posted

Generic Method to Convert DataReader Result into List of CLR Objects

, 24 Apr 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
Converting DataReader Result into List of Objects Using Generic Type, Property Attribute and Reflection

Introduction

Here is a simple and clean way to convert result set of DataReader into List of Data Model Objects of your application.

The logic presented below converts IDataReader Result into IEnumerable<T> with the help of Property Attribute and Reflection.

Background

There are so many Pattern Based Development Models and Frameworks for Application Development. However, there remains need of some simple, clean yet powerful code to address tiny challenges of small applications, where those giants are not an ideal fit.

So in this case, I have created a class DbHelper, attribute DataField and routine extractDataObjects that can be used along with a Generic Class Type to get enumerable collection of data objects.

Using the Code

There is an Property Attribute DataField that allows you to associate Source and Target element name along with respective data type. There is also a class DbHelper that exposes routine to perform the task.

[System.AttributeUsage( AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false )]
public class DataField: Attribute {
        public string dbField { get; set; }
        public string sourceType { get; set; }
        public string sourceDataFormatter { get; set; }
        public string targetDataFormatter { get; set; }
}      

public static class DbHelper {

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="dataSource"></param>
    /// <returns></returns>
    public static IEnumerable<T> extractDataObjects<T>( IDataReader dataSource ) 
    where T: class, new() {

        LinkedList<T> dataList         = new LinkedList<T>();
        PropertyInfo[] properties     = typeof( T ).GetProperties();
        T item = null;

        Type tAttrib = typeof( DataField );

        using ( dataSource ) {
             while ( dataSource.Read() ) {
                    item = new T();
                    foreach ( PropertyInfo property in properties ) {
                        var attribute = Attribute.GetCustomAttribute( property, tAttrib ) as DataField;  
            if ( attribute != null ) {
                var value = castValue( dataSource[attribute.dbField 
                                ?? property.Name]
                            , attribute.sourceType 
                                ?? "System.String"
                            , property.PropertyType );
                
                property.SetValue( item, value, null ); // null means no indexes
                        }
                    }

                    dataList.AddLast( item );
                }

                dataSource.Close();
                dataSource.Dispose();
            }

            return dataList;
        }

        private static object castValue( object value, string sourceType, Type targetType ) {
    //* This implementation requires further extension to convert types as per requirement arose.
            switch ( sourceType ) {
                case "System.DateTime":
                    switch ( targetType.Name ) {
                        case"TimeSpan":
                            var dtValue = (DateTime) value;
                            TimeSpan tsValue = dtValue.TimeOfDay;
                            value = tsValue;
                            break;
                    }
                    break;
            }
            
            return value;
        }
} 

//* Usage 

using ( IDbConnection instConn = dacFactory.getConnection( connectionSource.MSAccess, AppSettings.ConnectionString ) ) {
    using ( IDbCommand instCmd = dacFactory.getCommand( "SELECT * FROM PublisherLog"
                                , instConn ) ) {
                    dataList = dbHelper.extractDataObjects<publisherLogEntity>( 
                                    instCmd.ExecuteReader() );
                    instCmd.Cancel();
                    instCmd.Dispose();
    }

        instConn.Close();
        instConn.Dispose();
} 

public class publisherLogEntity {
        [DataField( dbField="IdPublising", sourceType= "System.Int64")]
        public long IdPublising { get; set; }
        [DataField( dbField="message", sourceType="System.String" )]
}  

Points of Interest

This is an easy application of reflection and generic to meet a common requirement to reduce several lines of code.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Bankey Sharma
Software Developer
India India
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionMy Vote of 4 Pin
Sebastien GASPAR6-May-14 5:59
memberSebastien GASPAR6-May-14 5:59 
QuestionDon't be a monkey 2, be monkey 3. Pin
hollysong24-Apr-14 22:32
memberhollysong24-Apr-14 22:32 
AnswerRe: Don't be a monkey 2, be monkey 3. Pin
FatCatProgrammer25-Apr-14 5:46
memberFatCatProgrammer25-Apr-14 5:46 
GeneralRe: Don't be a monkey 2, be monkey 3. Pin
hollysong27-Apr-14 22:18
memberhollysong27-Apr-14 22:18 
AnswerRe: Don't be a monkey 2, be monkey 3. Pin
Bankey Sharma25-Apr-14 7:15
memberBankey Sharma25-Apr-14 7:15 
GeneralRe: Don't be a monkey 2, be monkey 3. Pin
hollysong27-Apr-14 22:21
memberhollysong27-Apr-14 22:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.160721.1 | Last Updated 24 Apr 2014
Article Copyright 2014 by Bankey Sharma
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid