从数据库读取时如何提高通用循环的速度

时间:2019-02-07 05:34:28

标签: c# database generics

我有一个映射功能,可以从数据库加载的数据中读取数据。 它映射到通过泛型的类。

问题在于,遍历10000条记录需要3分钟。 我想提高其性能,我正在寻找解决方案吗?

public static List<T> GetList<T>(string query = null, string whereClause = null, Dictionary<string, string> Params = null)
{
        var results = new List<T>();
        var properties = GetReadableProperties<T>();
        query = QueryMaker.SelectQuery<T>(query, whereClause);

        using (SqlConnection Connection = new SqlConnection(ConnectionString))
        {
            Connection.Open();
            SqlCommand cmd = GetSqlCommandWithParams(query, Connection, Params);
            SqlDataReader reader = cmd.ExecuteReader();

            if (reader.HasRows)
            {
                // From here 
                while (reader.Read())
                {
                    var item = Activator.CreateInstance<T>();

                    foreach (var property in properties)
                    {
                        DBReader(item, property, reader);
                    }

                    results.Add(item);
                }

                // To here. It takes 3 minutes. reading a 10000 record from database into reader isn't as slow as this code is.
            }

            Connection.Close();
            return results;
        }
}

这是DBReader函数:

private static void DBReader(Object _Object, PropertyInfo property, SqlDataReader reader)
{
        if (!reader.IsDBNull(reader.GetOrdinal(property.Name)))
        {
            Type convertTo = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
            property.SetValue(_Object, Convert.ChangeType(reader[property.Name], convertTo), null);
        }
        else
        {
            property.SetValue(_Object, null);
        }
}

1 个答案:

答案 0 :(得分:2)

从理论上我可以看到许多可以改进的地方。例如:

  • 存储GetOrdinal的结果以在获取值时重复使用。
  • 使用通用的new()代替Activator.CreateInstance。
  • 您可以将表达式预编译为Func<>,然后为每一行调用它,而不是使用反射。
  • 根据所需的类型调用适当的Get...()方法,以避免装箱和拆箱。

但是所有这些都是微观优化,即使将它们全部组合在一起也不大可能产生显着差异。您描述的时间量(数万行的分钟数)不太可能是由这些问题引起的。它很可能来自某处的I / O操作,但是如果不对代码进行概要分析以了解花费最多的时间是不可能的。分析您的代码,然后使用这些结果来告知您采用的方法。