有关优化 C# 代码的建议
本文关键字:代码 优化 | 更新日期: 2023-09-27 17:56:50
我编写了一个通用的数据库帮助程序方法,该方法返回特定实体的记录。
这是我的做法:
-
我有一个名为 Customer 的类,该类具有 10 个属性,也具有一个名为 TableName 的属性。
-
有一个方法只接受类型参数,并返回一个传递类型的数组。
-
该方法的工作原理是,通过使用反射,它得到了一个表名,并触发了一个选择语句,并在 DataReader 的基础上循环遍历传递类型的每个列和属性。
因此,问题是假设有 100 万条记录和 10 个属性。 它循环 10(属性)*(1,000,000 条记录)= 10,000,000 次
是否有任何优化的方法可以做到这一点,比如对数据读取器使用 LINQ?
这是一个代码
object[] LoadAll(Type type)
{
try
{
object obj = Activator.CreateInstance(type);
SqlConnection conn = new SqlConnection("connection string");
string tableName = type.GetField("TableName").GetValue(obj) as string;
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = string.Format("select * from {0}", tableName);
conn.Open();
List<object> list = new List<object>();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
object obj1 = Activator.CreateInstance(type);
foreach (PropertyInfo propertyInfo in type.GetProperties())
{
obj.GetType().GetProperty(propertyInfo.Name).SetValue(obj1,reader[propertyInfo.Name],null);
}
list.Add(obj1);
}
}
感谢
尝试像NHibernate这样的对象关系映射器。
听起来您正在计算实体的每个实例的大小。 您应该有一些元数据控制器,用于缓存每个表名的实体大小。 假设我正确理解您的问题,对于相同的表名,大小将始终相同。
如果我正确地理解了这个问题,听起来你可以简单地让数据库为你完成工作。你说"并触发一个选择语句":你能不能触发一个更聪明的选择语句来做你所解释的?
我不完全明白当你说你正在循环浏览每一列时你想做什么。但是查看"分组依据"和"aggrop"又名"聚合运算符",看看其中是否有任何可以帮助您。
从优化的角度来看,没有必要为100万条记录维护与db的连接,这意味着您正在与数据库进行交互,直到循环结束。 :( .为了优化,您将整个表记录缓存在某个数据集中,然后迭代它。长时间不将连接实时连接到数据库。希望这将是你的问题.:)
收紧循环以减少涉及反射的调用。您也不需要创建该初始obj
:
PropertyInfo[] properties = type.GetProperties();
while (reader.Read())
{
object obj = Activator.CreateInstance(type);
foreach (PropertyInfo propertyInfo in properties)
{
propertyInfo.SetValue(obj, reader[propertyInfo.Name], null);
}
list.Add(obj);
}
但是为了更快地获得它,您可以为 pass LoadAll()
函数提供一种将行映射到新对象的方法,类似于:
IEnumerable<T> LoadAll<T>(Func<DataReader, T> map) {
var tablename = typeof(T).GetField("TableName)......
// other connection and query stuff
while (reader.Read()) {
yield return map(reader);
}
}
// use it like:
var kittens = LoadAll<Kitten>(reader => new Kitten {
Name = (string)reader["Name"],
Colour = (string)reader["Colour"]
});
这也使您可以更好地控制从数据层到域对象的映射,例如,使用反射的方法需要大量修改来处理enum
属性,这对于显式映射函数中的代码来说很简单。
您可以尝试安装ReSharper的免费试用版,其检查工具可以建议多种方法来从头开始优化代码。