C#性能优化篇 - 基于索引器封装EPList
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; namespace MyDemo.Web { /// <summary> /// EPList 支持为List创建索引 /// </summary> /// <typeparam name="T">类型</typeparam> public class EPList<T> { #region 成员变量 /// <summary> /// 索引 /// </summary> private List<string[]> m_Index = new List<string[]>(); /// <summary> /// 缓存数据 /// </summary> private Dictionary<string, List<T>> m_CachedData = new Dictionary<string, List<T>>(); /// <summary> /// List数据源 /// </summary> private List<T> m_ListData = new List<T>(); /// <summary> /// 通过索引值取数据 /// </summary> /// <param name="indexFields">索引字段</param> /// <param name="fieldValues">字段值</param> /// <returns></returns> public List<T> this[string[] indexFields] { get { string key = string.Join(",", indexFields); if (m_CachedData.ContainsKey(key)) return m_CachedData[key]; return new List<T>(); } } #endregion #region 公共方法 /// <summary> /// 创建索引 /// </summary> /// <param name="indexFields">索引字段</param> public void CreateIndex(string[] indexFields) { if (m_Index.Contains(indexFields)) return; m_Index.Add(indexFields); } /// <summary> /// 添加 /// </summary> /// <param name="record">记录</param> public void Add(T record) { m_ListData.Add(record); m_Index.ForEach(indexFields => { string key = getKey(record, indexFields); if (m_CachedData.ContainsKey(key)) { m_CachedData[key].Add(record); } else { List<T> list = new List<T> { record }; m_CachedData.Add(key, list); } }); } #endregion #region 私有方法 /// <summary> /// 获取值 /// </summary> /// <param name="record">记录</param> /// <param name="fieldName">字段名</param> /// <returns></returns> private object getValue(T record, string fieldName) { Type type = typeof(T); PropertyInfo propertyInfo = type.GetProperty(fieldName); return propertyInfo.GetValue(record, null); } /// <summary> /// 获取Key /// </summary> /// <param name="record">记录</param> /// <param name="indexFields">索引字段</param> private string getKey(T record, string[] indexFields) { List<string> values = new List<string>(); foreach (var field in indexFields) { string value = Convert.ToString(getValue(record, field)); values.Add(field + ":" + value); } return string.Join(",", values); } /// <summary> /// 获取Key /// </summary> /// <param name="indexFields">索引字段</param> /// <param name="fieldValues">字段值</param> /// <returns></returns> private string getKey(string[] indexFields, object[] fieldValues) { if (indexFields.Length != fieldValues.Length) return string.Empty; for (int i = 0; i < indexFields.Length; i++) { fieldValues[i] = indexFields[i] + ":" + fieldValues[i]; } string key = string.Join(",", fieldValues); return key; } #endregion } }
给EPList创建索引,并添加数据
private EPList<SysDepartInfo> GetEPListData() { EPList<SysDepartInfo> eplist = new EPList<SysDepartInfo>(); eplist.CreateIndex(new string[] { "ParentId" }); string sql = "select Id,ParentId,Code,Name from SysDepart"; SqlHelper.ExecuteReader(sql, null, (reader) => { SysDepartInfo record = new SysDepartInfo(); record.Id = Convert.ToString(reader["Id"]); record.ParentId = Convert.ToString(reader["ParentId"]); record.Code = Convert.ToString(reader["Code"]); record.Name = Convert.ToString(reader["Name"]); eplist.Add(record); }); return eplist; }
通过索引高效查询数据
/// <summary> /// 获取子节点 /// </summary> /// <param name="data"></param> /// <param name="parentId"></param> private IEnumerable<TreeInfo> CreateChildren(EPList<SysDepartInfo> data, TreeInfo node) { string id = node == null ? "0" : node.id; List<TreeInfo> childNodes = new List<TreeInfo>();
// ParentId字段上创建了索引,所以这里就可以通过索引值直接取出下一层子节点数据,避免Linq查询引发的效率问题 var indexValues = new string[] { "ParentId:" + id }; var childData = data[indexValues]; childData.ForEach(record => { var childNode = new TreeInfo { id = record.Id, text = record.Code + " " + record.Name }; childNodes.Add(childNode); childNode.children = CreateChildren(data, childNode); }); return childNodes.OrderBy(record => record.text); }