需要更有效的方法将实体转换为DataTable

时间:2012-08-24 18:31:13

标签: entity-framework datatable converter

所以我有一个将实体转换为DataTable的方法。唯一的问题是地狱很慢。我确保在IQueryable上调用.ToList()来使lazy turd继续并在处理结果之前加载到DataTable中。几乎没有时间将3000多行加载到内存中。但是,实时杀手是在方法的以下迭代中:

foreach (var index in imgLeaseIndexes)
        {
            DataRow dataRow = dataTable.NewRow();

            dataRow["StateCode"] = index.StateCode;
            dataRow["CountyCode"] = index.CountyCode;
            dataRow["EntryNumber"] = index.EntryNumber;
            dataRow["Volume"] = index.Volume;
            dataRow["Page"] = index.Page;
            dataRow["PageCount"] = index.ImgLocation.PageCount;
            dataRow["CreateDate"] = index.ImgLocation.CreateDate;

            dataTable.Rows.Add(dataRow);
        }

以下是完整的方法:

private DataTable buildImgLeaseIndexDataTable(List<ImgLeaseIndex> imgLeaseIndexes)
    {
        var dataTable = new DataTable();
        var dataColumns = new List<DataColumn>(); 
        var tdiReportProperties = 
            new List<string>() { "StateCode", "CountyCode", "EntryNumber", "Volume", "Page", "PageCount", "CreateDate" };

        Type imgLeaseIndexType = imgLeaseIndexes.FirstOrDefault().GetType();
        PropertyInfo[] imgLeaseIndexPropertyInfo = imgLeaseIndexType.GetProperties();

        dataColumns.AddRange(
            (from propertyInfo in imgLeaseIndexPropertyInfo
             where tdiReportProperties.Contains(propertyInfo.Name)
             select new DataColumn()
             {
                 ColumnName = propertyInfo.Name,
                 DataType = (propertyInfo.PropertyType.IsGenericType && 
                    propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) ? 
                    propertyInfo.PropertyType.GetGenericArguments()[0] : propertyInfo.PropertyType
             })
             .ToList());

        Type imgLocationType = imgLeaseIndexes.FirstOrDefault().ImgLocation.GetType();
        PropertyInfo[] imgLocationPropertyInfo = imgLocationType.GetProperties();

        dataColumns.AddRange(
            (from propertyInfo in imgLocationPropertyInfo
             where tdiReportProperties.Contains(propertyInfo.Name)
             select new DataColumn()
             {
                 ColumnName = propertyInfo.Name,
                 DataType = (propertyInfo.PropertyType.IsGenericType &&
                    propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) ?
                    propertyInfo.PropertyType.GetGenericArguments()[0] : propertyInfo.PropertyType
             })
             .ToList());

        dataTable.Columns.AddRange(dataColumns.ToArray());

        foreach (var index in imgLeaseIndexes)
        {
            DataRow dataRow = dataTable.NewRow();

            dataRow["StateCode"] = index.StateCode;
            dataRow["CountyCode"] = index.CountyCode;
            dataRow["EntryNumber"] = index.EntryNumber;
            dataRow["Volume"] = index.Volume;
            dataRow["Page"] = index.Page;
            dataRow["PageCount"] = index.ImgLocation.PageCount;
            dataRow["CreateDate"] = index.ImgLocation.CreateDate;

            dataTable.Rows.Add(dataRow);
        }

        return dataTable;
    }

有没有人有关于如何提高效率以及为什么它如此缓慢的想法?

更新

我删除了反射并根据我到目前为止收到的反馈在编译时显式设置数据列,但它仍然非常慢。这是更新后的代码:

private DataTable buildImgLeaseIndexDataTable(List<ImgLeaseIndex> imgLeaseIndexes)
    {
        var dataTable = new DataTable();

        var stateCodeDataColumn = new DataColumn();
        stateCodeDataColumn.ColumnName = "StateCode";
        stateCodeDataColumn.Caption = "State Code";
        stateCodeDataColumn.DataType = typeof(Int16);
        dataTable.Columns.Add(stateCodeDataColumn);

        var countyCodeDataColumn = new DataColumn();
        countyCodeDataColumn.ColumnName = "CountyCode";
        countyCodeDataColumn.Caption = "County Code";
        countyCodeDataColumn.DataType = typeof(Int16);
        dataTable.Columns.Add(countyCodeDataColumn);

        var entryNumberDataColumn = new DataColumn();
        entryNumberDataColumn.ColumnName = "EntryNumber";
        entryNumberDataColumn.Caption = "Entry Number";
        entryNumberDataColumn.DataType = typeof(string);
        dataTable.Columns.Add(entryNumberDataColumn);

        var volumeDataColumn = new DataColumn();
        volumeDataColumn.ColumnName = "Volume";
        volumeDataColumn.DataType = typeof(string);
        dataTable.Columns.Add(volumeDataColumn);

        var pageDataColumn = new DataColumn();
        pageDataColumn.ColumnName = "Page";
        pageDataColumn.DataType = typeof(string);
        dataTable.Columns.Add(pageDataColumn);

        var pageCountDataColumn = new DataColumn();
        pageCountDataColumn.ColumnName = "PageCount";
        pageCountDataColumn.Caption = "Page Count";
        pageCountDataColumn.DataType = typeof(string);
        dataTable.Columns.Add(pageCountDataColumn);

        var createDateDataColumn = new DataColumn();
        createDateDataColumn.ColumnName = "CreateDate";
        createDateDataColumn.Caption = "Create Date";
        createDateDataColumn.DataType = typeof(DateTime);
        dataTable.Columns.Add(createDateDataColumn);

        foreach (var index in imgLeaseIndexes)
        {
            DataRow dataRow = dataTable.NewRow();

            dataRow["StateCode"] = index.StateCode;
            dataRow["CountyCode"] = index.CountyCode;
            dataRow["EntryNumber"] = index.EntryNumber;
            dataRow["Volume"] = index.Volume;
            dataRow["Page"] = index.Page;
            dataRow["PageCount"] = index.ImgLocation.PageCount;
            dataRow["CreateDate"] = index.ImgLocation.CreateDate;

            dataTable.Rows.Add(dataRow);
        }

        return dataTable;
    }

关于还有什么可能导致这种情况的任何想法?

更新2:

所以看起来其他人有这个问题 - 特定于创建和设置DataRows。我的同事遇到了这个:

The DataRow value setter is slow!

我将尝试链接中建议的一些内容。

1 个答案:

答案 0 :(得分:0)

正如蒂亚戈在评论中提到的那样,问题在于使用反思。

反射部分是您使用PropertyInfo的地方。您将在运行时获取数据类型的结构。但这些在编译时是已知的。