7
    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 プロセスは成長しませんが、II6 プロセスを使用するページにヒットすると、成長します。

現在、ANTS Profiler を取得して詳細を提供しています。

4

1 に答える 1

9

それは実際のリークではありませんが、不必要に物事にストレスを与える可能性があります...

何行作業していますか?リフレクションは面倒であり、のようなものを呼び出すたびにGetCustomAttributes新しい配列が返される可能性があることに注意してください(したがって、行ごとにプロパティごとに1回ではなく、1回だけ実行する必要があります)。

個人的には、自分がやろうとしている仕事を事前に構築していきます...以下のようなものです。

これをたくさん行う場合は、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;        
}
于 2009-02-13T10:07:02.397 に答える