0

所以,我有一个将实体转换为 DataTable 的方法。唯一的问题是它非常慢。我确保在 IQueryable 上调用 .ToList() 以使其继续加载,然后再将结果处理到 DataTable 中。将 3000 多行加载到内存中几乎不需要任何时间。但是,实时slayer在方法中是在下面的迭代中:

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。我的同事遇到了这个:

DataRow 值设置器很慢!

我将尝试链接中建议的一些东西。

4

1 回答 1

0

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

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

于 2012-08-25T20:59:46.987 回答