使用泛型和扩展方法将DataTable转换为Dictionary <t1,t2> </t1,t2>

时间:2012-02-16 05:33:31

标签: c# generics extension-methods

我正在尝试从我的DataTable创建一个Dictionary。目前,我首先创建一个IList,然后循环遍历List并将它们添加到一个字典中,并根据具体情况单独指定列表中结果对象的主键属性。

我想知道是否可以使用泛型来完成。

我目前有以下代码,它不编译或工作:

public static IDictionary<T1, T2> ToDictionary<T1,T2>(this DataTable table) where T2 : new()
{
    IList<PropertyInfo> properties = GetPropertiesForType<T2>();
    IDictionary<T1,T2> result = new Dictionary<T1,T2>();
    Dictionary<string, int> propDict = GetPropertyDictionary(properties, table);
    T1 PK;
    foreach (var row in table.Rows)
    {
        var item = CreateDictItemFromRow<T2>((DataRow)row, properties, propDict);
        result.Add(item. item); //not sure here
    }
    return result;
}

基本上我想打电话给以下人员:

Dictionary<int, MyDBClass> Items = DataTable.ToDictionary<int,MyDBClass>();

Dictionary<Int16,MyDBClass> Items = DataTable.ToDictionary<Int16, MyDBClass>();

我假设我需要将主键属性名称传递给此函数。如果失败我可以安全地假设我的数据表中的第一列包含主键(虽然假设它总是一个int(可能是一个短或字节)是不安全的。)

我也明白使用LINQ可以很容易地做到这一点,但我还没有在C#中做到这一点,并希望改变现有的应用程序。

非常感谢帮助。

4 个答案:

答案 0 :(得分:4)

希望这有帮助。

        public static class Extensions
        {
            public static Dictionary<TKey, TRow> TableToDictionary<TKey,TRow>(
                this DataTable table,
                Func<DataRow, TKey> getKey,
                Func<DataRow, TRow> getRow)
            {
                return table
                    .Rows
                    .OfType<DataRow>()
                    .ToDictionary(getKey, getRow);
            }
        }



        public static void SampleUsage()
        {
            DataTable t = new DataTable();

            var dictionary = t.TableToDictionary(
                row => row.Field<int>("ID"),
                row => new {
                    Age = row.Field<int>("Age"),
                    Name = row.Field<string>("Name"),
                    Address = row.Field<string>("Address"),
                });
        }

顺便说一下,你需要包含程序集System.Data.DataSetExtensions.dll来使用Field扩展方法。

如果您有任何其他问题,请不要犹豫。

答案 1 :(得分:2)

在base2的帮助下,这是我完成的方法:

public static IDictionary<TKey, T> ToDictionary<TKey, T>(this DataTable table, Func<DataRow,TKey> getKey) where T : new()
{
    IList<PropertyInfo> properties = GetPropertiesForType<T>();
    IDictionary<TKey, T> result = new Dictionary<TKey, T>();
    Dictionary<string, int> propDict = GetPropertyDictionary(properties, table);
    foreach (var row in table.Rows)
    {
        var item = CreateItemFromRow<T>((DataRow)row, properties, propDict);
        TKey pk = getKey((DataRow)row);
        result.Add(pk,item);
    }
    return result;
}

可以像这样调用:

IDictionary<Int16,DBClient> Clients = sql.GetDataTable("SELECT * FROM Clients").ToDictionary<Int16,DBClient>(r => r.Field<Int16>("PrimaryKeyField"));

答案 2 :(得分:1)

签出Petapoco它允许您从数据库中检索CLR对象和列表。它没有太多开销。

答案 3 :(得分:0)

这可以通过反映检查来实现link可能对您有所帮助 在这篇文章中,我试图将数据集转换为列表