Преобразование DataTable в общий список?

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

То, о чем мы сейчас можем думать, это то, что мы должны делать что-то там, где нам нужно, чтобы Мусор собирал самих себя?

Мысли?

Почему мы думаем, что может произойти утечка?:

Мы получаем ошибки из памяти. Если на странице не требуется, чтобы бизнес-логика использовала этот тип преобразования, процесс II6 не растет, но когда мы попадаем на страницу, которая его использует, она растет.

В настоящее время мы получаем ANTS Profiler, чтобы предоставить нам более подробную информацию.

Ответ 1

Это не будет настоящей утечкой, но это может быть лишним лишним...

Сколько строк вы работаете? Обратите внимание, что отражение - это боль, и каждый вызов таких вещей, как GetCustomAttributes, может возвращать новый массив (поэтому вы хотите сделать это один раз, а не один раз для каждого свойства).

Лично я предварительно подготовил работу, которую я намерен сделать... что-то вроде ниже.

Обратите внимание, что если бы я делал этот лот, я бы либо переключился на HyperDescriptor, или если .NET 3.5 был вариантом, возможно, скомпилированное выражение. Поскольку DataTable не является строго типизированным, HyperDescriptor будет логическим следующим шагом (для производительности) после ниже...

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