How do I transform a List into a DataSet?

前端 未结 5 651
故里飘歌
故里飘歌 2020-12-02 13:00

Given a list of objects, I am needing to transform it into a dataset where each item in the list is represented by a row and each property is a column in the row. This DataS

相关标签:
5条回答
  • 2020-12-02 13:03

    I found this code on Microsoft forum. This is so far one of easiest way, easy to understand and use. This has saved me hours. I have customized this as extension method without any change to actual implementaion. Below is the code. it doesn't require much explanation.

    You can use two function signature with same implementation

    1) public static DataSet ToDataSetFromObject(this object dsCollection)

    2) public static DataSet ToDataSetFromArrayOfObject( this object[] arrCollection). I'll be using this one in below example.

    // <summary>
    // Serialize Object to XML and then read it into a DataSet:
    // </summary>
    // <param name="arrCollection">Array of object</param>
    // <returns>dataset</returns>
    
    public static DataSet ToDataSetFromArrayOfObject( this object[] arrCollection)
    {
        DataSet ds = new DataSet();
        try {
            XmlSerializer serializer = new XmlSerializer(arrCollection.GetType);
            System.IO.StringWriter sw = new System.IO.StringWriter();
            serializer.Serialize(sw, dsCollection);
            System.IO.StringReader reader = new System.IO.StringReader(sw.ToString());
            ds.ReadXml(reader);
        } catch (Exception ex) {
            throw (new Exception("Error While Converting Array of Object to Dataset."));
        }
        return ds;
    }
    

    To use this extension in code

    Country[] objArrayCountry = null;
    objArrayCountry = ....;// populate your array
    if ((objArrayCountry != null)) {
        dataset = objArrayCountry.ToDataSetFromArrayOfObject();
    }
    
    0 讨论(0)
  • 2020-12-02 13:14

    Apart from additionally using Reflection to determine the properties of class Record to take care of adding new properties, that's pretty much it.

    0 讨论(0)
  • 2020-12-02 13:19

    You can do it through reflection and generics, inspecting the properties of the underlying type.

    Consider this extension method that I use:

        public static DataTable ToDataTable<T>(this IEnumerable<T> collection)
        {
            DataTable dt = new DataTable("DataTable");
            Type t = typeof(T);
            PropertyInfo[] pia = t.GetProperties();
    
            //Inspect the properties and create the columns in the DataTable
            foreach (PropertyInfo pi in pia)
            {
                Type ColumnType = pi.PropertyType;
                if ((ColumnType.IsGenericType))
                {
                    ColumnType = ColumnType.GetGenericArguments()[0];
                }
                dt.Columns.Add(pi.Name, ColumnType);
            }
    
            //Populate the data table
            foreach (T item in collection)
            {
                DataRow dr = dt.NewRow();
                dr.BeginEdit();
                foreach (PropertyInfo pi in pia)
                {
                    if (pi.GetValue(item, null) != null)
                    {
                        dr[pi.Name] = pi.GetValue(item, null);
                    }
                }
                dr.EndEdit();
                dt.Rows.Add(dr);
            }
            return dt;
        }
    
    0 讨论(0)
  • 2020-12-02 13:21

    I've written a small library myself to accomplish this task. It uses reflection only for the first time an object type is to be translated to a datatable. It emits a method that will do all the work translating an object type.

    Its blazing fast. You can find it here: ModelShredder on GoogleCode

    0 讨论(0)
  • 2020-12-02 13:22

    I made some changes to CMS' extension method to handle the case when the List contains primitive or String elements. In that case the resulting DataTable will only have one Column with a Row for each of the values in the list.

    At first I thought of including all value types (not only primitive types) but I didn't want Structures (which are value types) to be included.

    This change arose from my need of converting a List(Of Long), or List<long>, into a DataTable to use it as a Table-Valued Parameter in a MS SQL 2008 Stored Procedure.

    I'm sorry my code is in VB even though this question is tagged c#; my project is in VB (NOT my choice) and it shouldn't be hard to apply the changes in c#.

    Imports System.Runtime.CompilerServices
    Imports System.Reflection
    
    Module Extensions
    
        <Extension()>
        Public Function ToDataTable(Of T)(ByVal collection As IEnumerable(Of T)) As DataTable
            Dim dt As DataTable = New DataTable("DataTable")
            Dim type As Type = GetType(T)
            Dim pia() As PropertyInfo = type.GetProperties()
    
            ' For a collection of primitive types create a 1 column DataTable
            If type.IsPrimitive OrElse type.Equals(GetType(String)) Then
                dt.Columns.Add("Column", type)
            Else
                ' Inspect the properties and create the column in the DataTable
                For Each pi As PropertyInfo In pia
                    Dim ColumnType As Type = pi.PropertyType
                    If ColumnType.IsGenericType Then
                        ColumnType = ColumnType.GetGenericArguments()(0)
                    End If
                    dt.Columns.Add(pi.Name, ColumnType)
                Next
    
            End If
    
            ' Populate the data table
            For Each item As T In collection
                Dim dr As DataRow = dt.NewRow()
                dr.BeginEdit()
                ' Set item as the value for the lone column on each row
                If type.IsPrimitive OrElse type.Equals(GetType(String)) Then
                    dr("Column") = item
                Else
                    For Each pi As PropertyInfo In pia
                        If pi.GetValue(item, Nothing) <> Nothing Then
                            dr(pi.Name) = pi.GetValue(item, Nothing)
                        End If
                    Next
                End If
                dr.EndEdit()
                dt.Rows.Add(dr)
            Next
            Return dt
        End Function
    
    End Module
    
    0 讨论(0)
提交回复
热议问题