web-dev-qa-db-ja.com

DataTableを辞書C#に変換する

DataTableを辞書に変換する方法を知りたいです。私はこのようなことをしました。

using System.Linq;

internal Dictionary<string,object> GetDict(DataTable dt)
{
    return dt.AsEnumerable()
      .ToDictionary<string, object>(row => row.Field<string>(0),
                                row => row.Field<object>(1));
}

しかし、私は得る:

System.Data.EnumerableRowCollectionには、 'ToDictionary'の定義と、 'System.Linq.Parallel.Enumerable.ToDictionary(System.Linq.ParallelQuery、System.Func、System.Collections.Generic.IEqualityComrparer)'の定義が含まれていません。無効な引数があります

どうすれば解決できますか?

ありがとう

30
Maximus Decimus

ジェネリックメソッドToDictionaryには3つのパラメーターがあります。 1つを中断したので、何をすべきかわかりません。すべてのパラメーターを指定する場合は、<DataRow, string, object>

internal Dictionary<string,object> GetDict(DataTable dt)
{
    return dt.AsEnumerable()
      .ToDictionary<DataRow, string, object>(row => row.Field<string>(0),
                                row => row.Field<object>(1));
}

もちろん、それらをオフのままにすると、コンパイラは型を推測できるため、エラーは発生しません。

71
cadrell0

以前の回答はすべて私を助けなかったので、私はこれをしました:

myList = dt.AsEnumerable()
.ToDictionary<DataRow, string, string>(row => row[0].ToString(),
                                       row => row[1].ToString()); 

うまくいきました!

14
ParPar

私はこの方法が好きです:

public static List<Dictionary<string, string>> GetDataTableDictionaryList(DataTable dt)
{
    return dt.AsEnumerable().Select(
        row => dt.Columns.Cast<DataColumn>().ToDictionary(
            column => column.ColumnName,
            column => row[column].ToString()
        )).ToList();
}

その理由は、このコードはToStringメソッドを呼び出すことでブール値やその他のデータ型も処理できるためです。

これにより辞書のリストが返されることに注意してください。各行にキーがある場合は、辞書の辞書に変更できます。

bool列を反復処理すると、次のようになります。

var list = GetDataTableDictionaryList(dt);

foreach (var row in list)
{
    if (row["Selected"].Equals("true", StringComparison.OrdinalIgnoreCase))
    {
        // do something
    }
}
6
Yakir Manor

ToDictionaryはIEnumberable<T>最初のタイプとして...あなたはそれが間違っている文字列であると言っていましたIEnumerable<DataRow>

あなたがタイプを指定することで混乱しています...これを試してください...

internal Dictionary<string,object> GetDict(DataTable dt)
{
    return dt.AsEnumerable()
      .ToDictionary(row => row.Field<string>(0),
                                row => row.Field<object>(1));
}
6
Kevin

私はこれがあなたを助けると思います:

            DataTable dt = new DataTable();
            dt.Columns.Add("Column1");
            dt.Columns.Add("Column2");
            dt.Rows.Add(1, "first");
            dt.Rows.Add(2, "second");
            var dictionary = dt.Rows.OfType<DataRow>().ToDictionary(d => d.Field<string>(0), v => v.Field<object>(1));
2
terrybozzio

私は解決策を見つけましたが、理由はわかりません。質問を編集してコードを完成させたのは、何をしていたのかを明確にするためです。これに変更しました

    internal Dictionary<string, object> GetDict(DataTable dt)
    {
        Dictionary<String, Object> dic = dt.AsEnumerable().ToDictionary(row => row.Field<String>(0), row => row.Field<Object>(1));
        return dic;
    }
1
Maximus Decimus

与えられたソリューションは2列のみを想定しています。複数列の表現が必要な場合は、辞書のリストが必要です

class Program
{
    static void Main(string[] args)
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("Column1");
        dt.Columns.Add("Column2");
        dt.Columns.Add("Column3");
        dt.Rows.Add(1, "first", "A");
        dt.Rows.Add(2, "second", "B");

        var dictTable = DataTableToDictionaryList(dt);
        var rowCount = dictTable.Count;
        var colCount = dictTable[0].Count;

        //Linq version
        var dictTableFromLinq = dt.AsEnumerable().Select(
                // ...then iterate through the columns...  
                row => dt.Columns.Cast<DataColumn>().ToDictionary(
                    // ...and find the key value pairs for the dictionary  
                    column => column.ColumnName,    // Key  
                    column => row[column] as string // Value  
                    )
                ).ToList();
    }

    public static List<Dictionary<string, object>> DataTableToDictionaryList(DataTable dt)
    {
        var result = new List<Dictionary<string, object>>();
        //or var result = new List<Dictionary<string, string>>();

        foreach (DataRow row in dt.Rows)
        {
            var dictRow = new Dictionary<string, object>();
            foreach (DataColumn col in dt.Columns)
            {
                dictRow.Add(col.ColumnName, row[col]);
                //or dictRow.Add(col.ColumnName, row[col].ToString());
            }

            result.Add(dictRow);
        }

        return result;
    }
}  
0
Pawel Cioch