我有一種方法,實質上是將一個數據錶轉換爲我稱之爲「包」的對象列表。這段代碼每次會話都會被調用很多次,其中很多會話會同時運行,有時會有數千行。正因爲如此,我需要它儘可能快。我有一個包含DataColumn屬性映射的XML文件。優化的主要方法是ConvertRowToBag
- 傳入的類型參數是從BagBase
派生的類型。該代碼如何優化?
這是一個很長的代碼,但任何提示將不勝感激。
public class BagBase
{
/// <summary>
/// Dictionary of properties and names
/// </summary>
private static Dictionary<string, PropertyInfo> propertyDictionary = new Dictionary<string, PropertyInfo>();
/// <summary>
/// Table of column/property mappings
/// </summary>
private static DataTable mappings = new DataTable("Mappings");
/// <summary>
/// Returns true if the map exists
/// </summary>
/// <param name="columnName"></param>
/// <param name="type"></param>
/// <returns></returns>
private static bool MappingExists(string columnName, Type type)
{
DataRow [] rows = BagBase.mappings.Select(String.Format("Type = '{0}' and ColumnName = '{1}'", type.Name, columnName));
return (rows != null && rows.Length > 0);
}
/// <summary>
/// Converts the table to bags.
/// </summary>
/// <param name="table">The table.</param>
/// <param name="outputType">Type of the output.</param>
/// <returns></returns>
protected static List<BagBase> ConvertTableToBags(DataTable table, Type outputType)
{
Trace.TraceInformation(String.Format("ConvertTableToBags : table={0} Type={1}", table.TableName, outputType.Name));
// Create an empty list
List<BagBase> result = new List<BagBase>();
// Iterate through the rows
foreach (DataRow row in table.Rows)
{
// Add to the list
result.Add(ConvertRowToBag(outputType, row));
}
Trace.TraceInformation("ConvertTableToBags Finished.");
return result;
}
/// <summary>
/// Converts the row to bag.
/// </summary>
/// <param name="outputType">Type of the output.</param>
/// <param name="row">The row.</param>
/// <returns></returns>
protected static BagBase ConvertRowToBag(Type outputType, DataRow row)
{
// Create an instance of the child class and store in the base
BagBase bag = Activator.CreateInstance(outputType) as BagBase;
// Iterate through the columns
foreach (DataColumn column in row.Table.Columns)
{
// If this column has been mapped
if (BagBase.MappingExists(column.ColumnName, outputType))
{
PropertyInfo property;
string columnProperty = String.Format("{0}={1}", column.ColumnName, outputType.Name);
// Get the property as defined in the map
if (!propertyDictionary.ContainsKey(columnProperty))
{
// Get the property
property = outputType.GetProperty(BagBase.GetColumnMapping(column.ColumnName, outputType));
// Add the property to the dictionary
propertyDictionary.Add(columnProperty, property);
}
else
{
property = propertyDictionary[columnProperty];
}
if (property != null)
{
if (!row.IsNull(column))
{
// Set the value to the in the table
if (property.PropertyType.BaseType != null && property.PropertyType.BaseType == typeof(Enum))
{
if (column.DataType != typeof(String))
{
property.SetValue(bag, Enum.ToObject(property.PropertyType, row[column]), null);
}
else
{
property.SetValue(bag, Enum.ToObject(property.PropertyType, Convert.ToChar(row[column])), null);
}
}
else if (property.PropertyType == typeof(DateTime?))
{
property.SetValue(bag, (DateTime?)row[column], null);
}
else
{
property.SetValue(bag, Convert.ChangeType(row[column], property.PropertyType), null);
}
}
else // No nulls
{
if (column.DataType == typeof(String))
{
property.SetValue(bag, String.Empty, null);
}
}
// Generate the unique class.property name
string propertyKey = String.Format("{0}.{1}", outputType.Name, property.Name);
if (!columnCaptions.ContainsKey(propertyKey))
{
// Add to the caption map
columnCaptions.Add(propertyKey, column.Caption);
}
}
}
else
{
// If this column isn't mapped, add it to Other information
if (bag.OtherInformation == null)
{
bag.OtherInformation = new Dictionary<string, string>();
}
bag.OtherInformation.Add(column.ColumnName, !row.IsNull(column) ? row[column].ToString() : String.Empty);
}
}
return bag;
}
}
分析應該確實揭示任何瓶頸,否則發佈在refactormycode.com可以給你更多的見解。 – Mez 2009-11-10 19:22:39
感謝您的鏈接 - 這是我第一次聽說該網站。 – 2009-11-10 19:35:41
refactormycode因維護而關閉 – TankorSmash 2014-12-03 17:57:16