Click here to Skip to main content
15,881,803 members
Articles / Programming Languages / C#
Alternative
Tip/Trick

Converting a List to a DataTable

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
20 Jul 2011CPOL 21.3K   1   1
Thanks for sharing. I have a similar utility with additional capabilities that some of you might find useful.using Microsoft.VisualBasic;using System;using System.Collections;using System.Collections.Generic;using System.Data;using System.Diagnostics;using...

Thanks for sharing. I have a similar utility with additional capabilities that some of you might find useful.


C#
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.ComponentModel;
using System.Reflection;
namespace Examples
{
    public delegate T CreateObjectDelegate<T>();
    public class ListHelper
    {
        private ListHelper()
        {
        }
        public static DataTable ConvertTo<T>(List<T> list)
        {
            DataTable table = CreateTable<T>();
            Type entityType = typeof(T);
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
            object value = null;
            DateTime dte = null;
            foreach (T item in list) {
                DataRow row = table.NewRow();
                foreach (PropertyDescriptor prop in properties) {
                    value = prop.GetValue(item);
                    if (value != null) {
                        if ((value) is DateTime) {
                            dte = (DateTime)value;
                            if (dte == DateTime.MinValue) {
                                row[prop.Name] = DBNull.Value;
                            } else {
                                row[prop.Name] = value;
                            }
                        } else {
                            row[prop.Name] = prop.GetValue(item);
                        }
                    } else {
                        row[prop.Name] = DBNull.Value;
                    }
                }
                table.Rows.Add(row);
            }
            return table;
        }
        public static List<T> ConvertTo<T>(List<DataRow> rows, 
                                           CreateObjectDelegate<T> del)
        {
            List<T> list = null;
            if (rows != null) {
                list = new List<T>();
                foreach (DataRow row in rows) {
                    T item = CreateItem<T>(row, del);
                    list.Add(item);
                }
            }
            return list;
        }
        public static List<T> ConvertTo<T>(List<DataRow> rows)
        {
            List<T> list = null;
            if (rows != null) {
                list = new List<T>();
                foreach (DataRow row in rows) {
                    T item = CreateItem<T>(row);
                    list.Add(item);
                }
            }
            return list;
        }
        public static List<T> ConvertTo<T>(DataRow[] rows)
        {
            List<T> list = null;
            if (rows != null) {
                list = new List<T>();
                foreach (DataRow row in rows) {
                    T item = CreateItem<T>(row);
                    list.Add(item);
                }
            }
            return list;
        }
        public static List<T> ConvertTo<T>(List<DataRow> rows, string sortString)
        {
            List<T> list = null;
            if (rows != null) {
                list = new List<T>();
                foreach (DataRow row in rows) {
                    T item = CreateItem<T>(row);
                    list.Add(item);
                }
                GenericSorter<T> sorter = new GenericSorter<T>(sortString);
                list.Sort(sorter);
            }
            return list;
        }
        public static List<T> ConvertTo<T>(DataTable dt, string sortString)
        {
            if (dt == null) {
                return null;
            }
            List<DataRow> rows = new List<DataRow>();
            foreach (DataRow row in dt.Rows) {
                rows.Add(row);
            }
            return ConvertTo<T>(rows, sortString);
        }
        public static List<T> ConvertTo<T>(DataTable dt)
        {
            if (dt == null) {
                return null;
            }
            List<DataRow> rows = new List<DataRow>();
            foreach (DataRow row in dt.Rows) {
                rows.Add(row);
            }
            return ConvertTo<T>(rows);
        }
        public static List<T> ConvertTo<T>(DataTable dt, CreateObjectDelegate<T> del)
        {
            if (dt == null) {
                return null;
            }
            List<DataRow> rows = new List<DataRow>();
            foreach (DataRow row in dt.Rows) {
                rows.Add(row);
            }
            return ConvertTo<T>(rows, del);
        }
        public static T CreateItem<T>(DataRow dr, CreateObjectDelegate<T> del)
        {
            T obj = null;

            if (dr != null) {
                if (del != null) {
                    obj = del.Invoke();
                } else {
                    obj = Activator.CreateInstance<T>();
                }
                if (obj != null) {
                    foreach (DataColumn column in dr.Table.Columns) {
                        PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);
                        if (prop != null) {
                            if (!object.ReferenceEquals(dr[column.ColumnName], DBNull.Value)) {
                                prop.SetValue(obj, dr[column.ColumnName], null);
                            } else {
                                prop.SetValue(obj, null, null);
                            }
                        }
                    }
                }
            }
            return obj;
        }
        public static T CreateItem<T>(DataRow dr)
        {
            T obj = null;
            if (dr != null) {
                obj = Activator.CreateInstance<T>();
                if (obj != null) {
                    foreach (DataColumn column in dr.Table.Columns) {
                        PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);
                        if (prop != null) {
                            if (!object.ReferenceEquals(dr[column.ColumnName], DBNull.Value)) {
                                prop.SetValue(obj, dr[column.ColumnName], null);
                            } else {
                                prop.SetValue(obj, null, null);
                            }
                        }
                    }
                }
            }
            return obj;
        }
        public static DataTable CreateTable<T>()
        {
            Type entityType = typeof(T);
            DataTable dt = new DataTable(entityType.Name);
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
            if (properties != null) {
                foreach (PropertyDescriptor prop in properties) {
                    dt.Columns.Add(prop.Name, prop.PropertyType);
                }
            }
            return dt;
        }
    }
    /// <summary>
    /// Sort order enumeration
    /// </summary>
    public enum SortOrder
    {
        Ascending,
        Descending
    }
    /// <summary>
    /// Sorts a generic collection of some object
    ///
    /// Example:
    ///     Dim MyList As List(Of MyClassType) = 'Populate the list somehow
    ///     Dim Sorter As New Sorter(Of MyClassType)    '''     Sorter.SortString = "Field1 DESC, Field2"
    ///     MyList.Sort(Sorter) 'After this call, the list is sorted
    /// </summary>
    public class GenericSorter<T> : IComparer<T>
    {

        private string _sort;
        /// <summary>
        /// Instantiate the class.
        /// </summary>
        public GenericSorter()
        {
        }
        /// <summary>
        /// Instantiate the class, setting the sort string.
        ///
        /// Example: "LastName DESC, FirstName"
        /// </summary>
        public GenericSorter(string SortString)
        {
            _sort = SortString;
        }
        /// <summary>
        /// The sort string used to perform the sort. Can sort on multiple fields.
        /// Use the property names of the class and basic SQL Syntax.
        ///
        /// Example: "LastName DESC, FirstName"
        /// </summary>
        public string SortString {
            get {
                if (_sort != null) {
                    return _sort.Trim();
                }
                return null;
            }
            set { _sort = value; }
        }
        /// <summary>
        /// This is an implementation of IComparer(Of T).Compare
        /// Can sort on multiple fields, or just one.
        /// </summary>
        public int Compare(T x, T y)
        {
            if (!string.IsNullOrEmpty(this.SortString)) {
                const string err = "The property \"{0}\" does not exist in type \"{1}\"";
                Type type = typeof(T);
                Comparer comp = Comparer.DefaultInvariant;
                PropertyInfo info = null;
                foreach (string expr in this.SortString.Split(',')) {
                    SortOrder dir = SortOrder.Ascending;
                    string field = null;
                    expr = expr.Trim();
                    if (expr.EndsWith(" DESC")) {
                        field = expr.Replace(" DESC", string.Empty).Trim();
                        dir = SortOrder.Descending;
                    } else {
                        field = expr.Replace(" ASC", string.Empty).Trim();
                    }
                    info = type.GetProperty(field);
                    if (info == null) {
                        throw new MissingFieldException(string.Format(err, field, type.ToString()));
                    } else {
                        int Result = comp.Compare(info.GetValue(x, null), info.GetValue(y, null));
                        if (Result != 0) {
                            if (dir == SortOrder.Descending) {
                                return Result * -1;
                            } else {
                                return Result;
                            }
                        }
                    }
                }
            }
            return 0;
        }
    }
}

License

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralReason for my vote of 5 Looks very well done! Pin
Mark Wing26-Jul-11 6:20
Mark Wing26-Jul-11 6:20 

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.