Конвертировать DataTable в общий список? - PullRequest
6 голосов
/ 13 февраля 2009
    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 Ответ

9 голосов
/ 13 февраля 2009

Это не будет реальной утечкой , но это может привести к ненужным стрессам ...

Сколько строк вы работаете над? Обратите внимание, что отражение - это боль, и что каждый вызов таких вещей, как 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;        
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...