将数据表转换为通用列表? [英] Convert DataTable to generic List?

查看:24
本文介绍了将数据表转换为通用列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

    public static IList<T> ConvertTo<T>(DataTable table)
    {
        if (table == null)
        {
            return null;
        }

        List<DataRow> rows = new List<DataRow>();

        foreach (DataRow row in table.Rows)
        {
            rows.Add(row);
        }

        return ConvertTo<T>(rows);
    }

    public static T ConvertItem<T>(DataTable table)
    {
        T obj = default(T);
        if (table != null && table.Rows.Count > 0)
        {
            obj = CreateItem<T>(table.Rows[0]);
        }
        return obj;
    }


    public static T CreateItem<T>(DataRow row)
    {
        T obj = default(T);
        if (row != null)
        {
            obj = Activator.CreateInstance<T>();
            Type entityType = typeof(T);
            PropertyInfo[] properties = entityType.GetProperties();

            for (int i = 0; i < properties.Length; i++)
            {
                object[] customAttributes = properties[i].GetCustomAttributes(typeof(ColumnAttributes), false);
                ColumnAttributes dataField = null;
                if (null != customAttributes && customAttributes.Length > 0 && null != (dataField = customAttributes[0] as ColumnAttributes))
                {
                    if (row.Table.Columns.Contains(dataField.FieldName) && !row[dataField.FieldName].GetType().FullName.Equals("System.DBNull"))
                    {
                        properties[i].SetValue(obj, row[dataField.FieldName], null);
                    }
                }
            }
        }
        return obj;
    }

那是我们现在唯一能想到的就是我们必须做一些我们需要自己收集垃圾的事情?

Thats the only thing we can think of right now is that we must be doing something where we need to Garbage collect Ourselves?

想法?

为什么我们认为可能存在泄漏?:

Why we think there might be a leak?:

我们遇到内存不足错误.如果一个 Page 不需要业务逻辑来使用这种类型的转换,那么 II6 进程不会增长,但是当我们点击一​​个使用它的页面时,它会增长.

We are getting Out of Memory Errors. If a Page does not require business logic to use this type of conversion, the II6 process does not grow, but when we hit a page that uses it, it grows.

我们目前正在让 ANTS Profiler 为我们提供更多详细信息.

We are currently getting ANTS Profiler to give us more details.

推荐答案

这不会是真正的泄密,但它可能会给事情带来不必要的压力...

That won't be an actual leak, but it could be stressing things unnecessarily...

您处理了多少行?请注意,反射是一种痛苦,并且每次调用诸如 GetCustomAttributes 之类的东西都可以返回一个新数组(因此您想这样做一次,而不是每行一次).

How many rows are you working over? Note that reflection is a pain, and that every call to things like GetCustomAttributes can return a new array (so you want to do that once, not once per-property-per-row).

就我个人而言,我会预先构建我打算做的工作......类似于下面的内容.

Personally, I'd pre-construct the work I intend to do... something like below.

请注意,如果我做了这么多,我要么切换到 HyperDescriptor,或者如果 .NET 3.5 是一个选项,可能是一个编译的表达式.由于 DataTable 不是强类型,HyperDescriptor 将是以下合乎逻辑的下一步(为了性能)...

Note that if I was doing this lots, I'd either switch to HyperDescriptor, or if .NET 3.5 was an option, maybe a compiled Expression. Since DataTable isn't strongly typed, HyperDescriptor would be a logical next step (for performance) after the below...

sealed class Tuple<T1, T2>
{
    public Tuple() {}
    public Tuple(T1 value1, T2 value2) {Value1 = value1; Value2 = value2;}
    public T1 Value1 {get;set;}
    public T2 Value2 {get;set;}
}
public static List<T> Convert<T>(DataTable table)
    where T : class, new()
{
    List<Tuple<DataColumn, PropertyInfo>> map =
        new List<Tuple<DataColumn,PropertyInfo>>();

    foreach(PropertyInfo pi in typeof(T).GetProperties())
    {
        ColumnAttribute col = (ColumnAttribute)
            Attribute.GetCustomAttribute(pi, typeof(ColumnAttribute));
        if(col == null) continue;
        if(table.Columns.Contains(col.FieldName))
        {
            map.Add(new Tuple<DataColumn,PropertyInfo>(
                table.Columns[col.FieldName], pi));
        }
    }

    List<T> list = new List<T>(table.Rows.Count);
    foreach(DataRow row in table.Rows)
    {
        if(row == null)
        {
            list.Add(null);
            continue;
        }
        T item = new T();
        foreach(Tuple<DataColumn,PropertyInfo> pair in map) {
            object value = row[pair.Value1];
            if(value is DBNull) value = null;
            pair.Value2.SetValue(item, value, null);
        }
        list.Add(item);
    }
    return list;        
}

这篇关于将数据表转换为通用列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆