質問

オブジェクトのリストを考えると、私は、リスト内の各項目は、行によって表されるデータセットにそれを変換するために必要と思い、各プロパティは、行の列です。このデータセットは、その後、= <のhref =「http://www.aspose.com/categories/file-format-components/aspose.cells-for-.net-and-java/default.aspx」RELに渡されます「noreferrer」>レポートとしてExcelドキュメントを作成するために、Aspose.Cellsはの機能ます。

私は次があるとします:

public class Record
{
   public int ID { get; set; }
   public bool Status { get; set; }
   public string Message { get; set; }
}
次のように

リストレコードを考えると、どのように私は、DataSetに変換します。

ID Status Message
1  true   "message" 
2  false  "message2" 
3  true   "message3" 
...
次のように

現時点では私は考えることができる唯一のことはあります:

DataSet ds = new DataSet
ds.Tables.Add();
ds.Tables[0].Add("ID", typeof(int));    
ds.Tables[0].Add("Status", typeof(bool));
ds.Tables[0].Add("Message", typeof(string));

foreach(Record record in records)
{
    ds.Tables[0].Rows.Add(record.ID, record.Status, record.Message);
}

しかし、この方法は、新しいプロパティがレコードに追加されている非常に少なくともならば、彼らはデータセットに表示されませんので、良い方法がなければならない考えを私に残します...が、同時にそれは私が制御することができます順序は、各プロパティは、行に追加されます。

誰もがこれを行うには良い方法を知っていますか?

役に立ちましたか?

解決

あなたは、基になる型の性質を検査、反射とジェネリックを通じてそれを行うことができます。

私が使用して、この拡張メソッドを考えてみます:

    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;
    }

他のヒント

は別にさらに新しいプロパティを追加するの世話をするために、クラスのReflectionの特性を決定するためにRecordを使用してから、それはかなりそれだ。

私は、Microsoftのフォーラムで、このコードを発見しました。これは、これまで理解し、使いやすい最も簡単な方法の一つです。これは私の時間を保存しています。私は、実際のimplementaionを変更せずに拡張メソッドとしてこれをカスタマイズしています。以下のコードです。それは多くの説明を必要としません。

あなたは同じ実装を持つ2つの関数のシグネチャを使用することができます。

1)パブリック静的データセットToDataSetFromObject(こののオブジェクトのdsCollection)

2)パブリック静的データセットToDataSetFromArrayOfObject(こののオブジェクト[] をarrCollection)。私は、下記の例では、このいずれかを使用しています。

// <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;
}

のコードでこの拡張機能を使用するには、

Country[] objArrayCountry = null;
objArrayCountry = ....;// populate your array
if ((objArrayCountry != null)) {
    dataset = objArrayCountry.ToDataSetFromArrayOfObject();
}

私は、このタスクを達成するために小さなライブラリを自分で書いています。それは唯一のオブジェクト・タイプがデータテーブルに変換する初めての反射を使用します。これは、オブジェクト型を変換するすべての作業を行います方法を発するます。

その高速燃えます。あなたがここでそれを見つけることができます: ModelShredder GoogleCode の上の

私はListプリミティブまたはStringの要素が含まれている場合を処理するためのCMS」拡張メソッドにいくつかの変更を行いました。その場合、得られたDataTableは、リスト中の値のそれぞれについてColumnと、ワンRowを有することになる。

最初に私はすべての値の型(プリミティブ型だけではなく)を含むものと考えるが、私は(値型である)の構造が含まれてほしくありませんでした。

この変更は、MS SQL 2008ストアドプロシージャでテーブル値パラメーターとしてそれを使用するList(Of Long)に、List<long>、またはDataTableを変換する私の必要性から生まれた。

私はこの質問がタグ付けされているにもかかわらず、私のコードはVBであるごめんなさい<クラス=「ポスト・タグ」のhref =「/質問/タグ付き/ Cの%23」タイトル=「『C#の』をタグ付けしました。ショーの質問」のrel = "タグ">#のC;私のプロジェクトは、VB(NOT私の選択)であり、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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top