Click here to Skip to main content
15,887,267 members
Please Sign up or sign in to vote.
4.00/5 (3 votes)
See more:
Hi,

I want to know something about Conversion of List<object> to DataTable.
I have searched for it on Google and Codeproject and found some article but every article says to iterate the List which I have already implemented.

Now, I want to know, is there any other better way to do this?
If any body can help me then it would be great for me.


Thanks in advance.

Regards
AR
Posted
Comments
wizardzz 4-May-11 13:37pm    
Why can't you iterate? I mean, out of curiosity, how would you expect to do this? Any conversion function would be iterating under the hood I think.
Ankit Rajput 4-May-11 15:06pm    
I have already implemented the iteration into my project and released to production.
Now to update my knowledge or you can say to find another way or better way to do something, I have raised this question.
wizardzz 4-May-11 15:10pm    
Well, you could post your code and we can tell you if there's anything inefficient. But why don't you like iterating?

Why do you want to avoid iteration?

If it is to reduce code, use LINQ (technically still iterates, but looks less like it's doing that):
C#
List<object> x = new List<object>();
DataTable d = new DataTable();
d.Columns.Add("item");
x.ForEach((item) => d.Rows.Add(item));


If you want to avoid the immediate performance hit of processing each item, you can derive a class from DataTable that wraps a List internally:
C#
public class MyDataTable<T> : DataTable
{
    private List<T> internalList { get; set; }
    public MyDataTable(List<T> p_internalList)
    {
        this.internalList = p_internalList;
    }
    //TODO: Your implementation here.
}

Pretty sure that wrapping technique is also used with the ReadOnlyCollection returned from List.AsReadOnly().
 
Share this answer
 
Comments
AspDotNetDev 4-May-11 13:49pm    
The DataTable wrapper would also have the advantage that less memory would be taken up if both the list and data table need to exist at once. And any modifications to the list will modify the DataTable automatically.
Wonde Tadesse 6-May-11 21:52pm    
Does this consider column data types ? More over does it consider the nullable column datatypes :(
AspDotNetDev 6-May-11 21:56pm    
No. In fact, it only uses a list of objects as an example. I didn't want to spood feed the answer to the OP.
Wonde Tadesse 6-May-11 21:53pm    
Please look my answer for detail.
Here is the full functioning code. It consider all the list object datatype and even check Nullable.

C#
/// <summary>
/// Converts a Generic List into a DataTable.
/// </summary>
/// <param name="genericList">Generic list</param>
/// <returns>DataTable object</returns>
private static DataTable GenericListToDataTable(object genericList)
{
    DataTable dataTable = null;
    Type listType = genericList.GetType();

    if (listType.IsGenericType & (genericList != null)) {
        //determine the underlying type the List<> contains
        Type elementType = listType.GetGenericArguments()[0];

        //create empty table -- give it a name in case
        //it needs to be serialized
        dataTable = new DataTable(elementType.Name + "List");

        //define the table -- add a column for each public
        //property or field
        MemberInfo[] memberInfos = elementType.GetMembers(BindingFlags.Public | BindingFlags.Instance);
        foreach (MemberInfo memberInfo in memberInfos) {
            if (memberInfo.MemberType == MemberTypes.Property) {
                PropertyInfo propertyInfo = memberInfo as PropertyInfo;
                if (IsNullableType(propertyInfo.PropertyType)) {
                    dataTable.Columns.Add(propertyInfo.Name, new NullableConverter(propertyInfo.PropertyType).UnderlyingType);
                } else {
                    dataTable.Columns.Add(propertyInfo.Name, propertyInfo.PropertyType);
                }
            } else if (memberInfo.MemberType == MemberTypes.Field) {
                FieldInfo fieldInfo = memberInfo as FieldInfo;
                dataTable.Columns.Add(fieldInfo.Name, fieldInfo.FieldType);
            }
        }

        //populate the table
        IList listData = genericList as IList;
        foreach (object record in listData) {
            int index = 0;
            object[] fieldValues = new object[dataTable.Columns.Count];
            foreach (DataColumn columnData in dataTable.Columns) {
                MemberInfo memberInfo = elementType.GetMember(columnData.ColumnName)[0];
                if (memberInfo.MemberType == MemberTypes.Property) {
                    PropertyInfo propertyInfo = memberInfo as PropertyInfo;
                    fieldValues[index] = propertyInfo.GetValue(record, null);
                } else if (memberInfo.MemberType == MemberTypes.Field) {
                    FieldInfo fieldInfo = memberInfo as FieldInfo;
                    fieldValues[index] = fieldInfo.GetValue(record);
                }
                index += 1;
            }
            dataTable.Rows.Add(fieldValues);
        }
    }
    return dataTable;
}

/// <summary>
/// Check if a type is Nullable type
/// </summary>
/// <param name="propertyType">Type to be checked</param>
/// <returns>true/false</returns>
/// <remarks></remarks>
private static bool IsNullableType(Type propertyType)
{
    return (propertyType.IsGenericType) && (object.ReferenceEquals(propertyType.GetGenericTypeDefinition(), typeof(Nullable<>)));
}
 
Share this answer
 
Comments
AspDotNetDev 6-May-11 21:58pm    
I don't see how this answers the OP's question. The OP already has an implementation of this. What the OP was asking (as far as I could tell) is how to do this without iteration (I see you are iterating over listData using a foreach loop).
Wonde Tadesse 7-May-11 21:14pm    
Agree. But the question should be Conversion of List to DataTable without iteration. Don't you agree ?. And How possible to do without traversing each list object ?
AspDotNetDev 7-May-11 21:52pm    
That would make the title more specific, but longer... you can change it if you like. My answer covers one possible solution (deriving a class from DataTable and returning rows on demand). I also provided another answer, as the OP didn't provide enough information to really tell what exactly they want.
 
Share this answer
 
Comments
Ankit Rajput 30-Apr-11 6:06am    
This one is the same method. We need to iterate in ToDataTable function. and I dont want to iterate in my code.
Ankit Rajput 30-Apr-11 6:06am    
By the way Thanks
 
Share this answer
 
Comments
Ankit Rajput 30-Apr-11 6:07am    
This one is the same method. We need to iterate in ToDataTable function. and I dont want to iterate in my code.

By the Thanks
Dave Kreskowiak 4-May-11 7:13am    
You don't hvae a choice. There is no way to convert a List to a DataTable without converting each item, one at a time, manually.
AspDotNetDev 4-May-11 13:41pm    
True, though one may be able to amortize the conversion using a derived version of DataTable.
The Solution 4 is perfect!!!
I did the convertion into VB. For whom wants:

VB
''' <summary>
''' Converts a Generic List into a DataTable.
''' </summary>
''' <param name="genericList"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function ConvertGenericListToDataTable(ByVal genericList As Object) As Data.DataTable

    Dim dataTable As Data.DataTable = Nothing
    Dim listType As Type = genericList.GetType()

    If (listType.IsGenericType AndAlso (genericList IsNot Nothing)) Then

        '//determine the underlying type the List<> contains
        Dim elementType As Type = listType.GetGenericArguments()(0)

        '//create empty table -- give it a name in case
        '//it needs to be serialized
        dataTable = New Data.DataTable(elementType.Name + "List")

        '//define the table -- add a column for each public
        '//property or field
        Dim memberInfos As MemberInfo() = elementType.GetMembers(BindingFlags.Public Or BindingFlags.Instance)
        For Each memberInfo As MemberInfo In memberInfos

            If (memberInfo.MemberType = MemberTypes.Property) Then

                Dim propertyInfo As PropertyInfo = CType(memberInfo, PropertyInfo)

                If IsNullableType(propertyInfo.PropertyType) Then
                    dataTable.Columns.Add(propertyInfo.Name, New ComponentModel.NullableConverter(propertyInfo.PropertyType).UnderlyingType)
                Else
                    dataTable.Columns.Add(propertyInfo.Name, propertyInfo.PropertyType)
                End If
            ElseIf (memberInfo.MemberType = MemberTypes.Field) Then
                Dim fieldInfo As FieldInfo = CType(memberInfo, FieldInfo)
                dataTable.Columns.Add(fieldInfo.Name, fieldInfo.FieldType)
            End If
        Next

        '//populate the table
        Dim listData As IList = CType(genericList, IList)
        For Each record As Object In listData
            Dim index As Integer = 0
            Dim fieldValues(dataTable.Columns.Count - 1) As Object ' = CType(New Object(), Object())
            For Each columnData As Data.DataColumn In dataTable.Columns
                Dim memberInfo As MemberInfo = elementType.GetMember(columnData.ColumnName)(0)
                If memberInfo.MemberType = MemberTypes.Property Then
                    Dim propertyInfo As PropertyInfo = CType(memberInfo, PropertyInfo)
                    fieldValues(index) = propertyInfo.GetValue(record, Nothing)
                ElseIf memberInfo.MemberType = MemberTypes.Field Then
                    Dim fieldInfo As FieldInfo = CType(memberInfo, FieldInfo)
                    fieldValues(index) = fieldInfo.GetValue(record)
                End If
                index += 1
            Next
            dataTable.Rows.Add(fieldValues)
        Next

    End If

    Return dataTable
End Function

''' <summary>
''' Check if a type is Nullable type
''' </summary>
''' <param name="propertyType"></param>
''' <returns></returns>
''' <remarks></remarks>
Private Shared Function IsNullableType(ByVal propertyType As Type) As Boolean

    Return (propertyType.IsGenericType) AndAlso (propertyType.GetGenericTypeDefinition() Is GetType(Nullable(Of )))

End Function
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900