EsayUI + MVC + ADO.NET(仓储基类)
该篇主要讲解工作单元的运用 和DbHlper抽象封装
工作单元仓储基类:BaseRepository (DbHlper抽象封装)
仓储接口(CRUD):IRepository (CRUD接口)
工作单元仓储基类:IUnitOfWorkRepository (工作单元仓储接口)
工作单元仓储基类: UnitOfWorkRepositoryBase (实现注册工作单元接口)
工作单元仓储基类: SqlRepositoryBase (创建数据读取工厂,加载子对象委托,创建实体对象方法)
仓储实现: Repository(改层主要是持久化数据)
BaseRepository (Code):
using System; using System.Data; using Notify.DbCommon.UnitOfWork; using Notify.Infrastructure.UnitOfWork; namespace Notify.DbCommon.Repositroies { /// <summary> /// 数据库持久化基类 /// </summary> public abstract class BaseRepository : IDisposable { /// <summary> /// 数据库链接 /// </summary> private IDbConnection connection; /// <summary> /// Command对象 /// </summary> private IDbCommand cmd; /// <summary> /// 工作单元接口 /// </summary> public IUnitOfWork UnitOfWork { get; private set; } /// <summary> /// 数据库链接 /// </summary> public string Name { get; private set; } /// <summary> /// Initializes a new instance of the <see cref="BaseRepository"/> class. /// 构造函数 /// </summary> /// <param name="unit">工作单元</param> /// <param name="name">数据库链接</param> protected BaseRepository(IUnitOfWork unit, string name) { this.Name = name; this.UnitOfWork = unit; if (unit != null) { this.cmd = unit.Command; } else { if (this.connection == null) { this.connection = DbFactories.GetConnection(name); } if (this.connection.State != ConnectionState.Open) { this.connection.Open(); } this.cmd = this.connection.CreateCommand(); } } #region Parameter /// <summary> /// 添加参数 /// </summary> /// <param name="name">参数名称</param> /// <returns>参数</returns> protected IDbDataParameter AddParameter(string name) { IDbDataParameter param = this.CreateParameter(name); this.cmd.Parameters.Add(param); return param; } /// <summary> /// 添加参数 /// </summary> /// <param name="name">参数名称</param> /// <param name="value">参数值</param> /// <returns>参数</returns> protected IDbDataParameter AddParameter(string name, object value) { IDbDataParameter param = this.CreateParameter(name, value); this.cmd.Parameters.Add(param); return param; } /// <summary> /// 添加参数 /// </summary> /// <param name="name">参数名称</param> /// <param name="value">参数值</param> /// <param name="type">参数类型</param> /// <returns>参数</returns> protected IDbDataParameter AddParameter(string name, object value, DbType type) { IDbDataParameter param = this.CreateParameter(name, value, type); this.cmd.Parameters.Add(param); return param; } /// <summary> /// 添加参数 /// </summary> /// <param name="name">参数名称</param> /// <param name="value">参数值</param> /// <param name="type">参数类型</param> /// <param name="direction">参数输出类型</param> /// <returns>参数</returns> protected IDbDataParameter AddParameter(string name, object value, DbType type, ParameterDirection direction) { IDbDataParameter param = this.CreateParameter(name, value, type, direction); this.cmd.Parameters.Add(param); return param; } /// <summary> /// 添加参数 /// </summary> /// <param name="name">参数名称</param> /// <param name="value">参数值</param> /// <param name="type">参数类型</param> /// <param name="direction">参数输出类型</param> /// <param name="size">参数大小</param> /// <returns>参数</returns> protected IDbDataParameter AddParameter(string name, object value, DbType type, ParameterDirection direction, int size) { IDbDataParameter param = this.CreateParameter(name, value, type, direction, size); this.cmd.Parameters.Add(param); return param; } /// <summary> /// 添加参数 /// </summary> /// <param name="name">参数名称</param> /// <param name="value">参数值</param> /// <param name="type">参数类型</param> /// <param name="direction">参数输出类型</param> /// <param name="size">参数大小</param> /// <param name="scale">显示数字参数的规模(精确到小数点后几位)</param> /// <returns>参数</returns> protected IDbDataParameter AddParameter(string name, object value, DbType type, ParameterDirection direction, int size, byte scale) { IDbDataParameter param = this.CreateParameter(name, value, type, direction, size, scale); this.cmd.Parameters.Add(param); return param; } /// <summary> /// 清除参数 /// </summary> protected void ClearParameters() { this.cmd.Parameters.Clear(); } #endregion #region ExecuteReader /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">读取类型(sql文本,存储过程,表)</param> /// <param name="behavior">提供了一个查询的结果的描述和对数据库的影响</param> /// <param name="timeout">超时时间</param> /// <returns>IDataReader</returns> protected IDataReader ExecuteReader(string sql, CommandType type, CommandBehavior behavior, int timeout) { if (string.IsNullOrWhiteSpace(sql)) { throw new ArgumentNullException("sql"); } this.cmd.CommandText = sql; this.cmd.CommandType = type; this.cmd.CommandTimeout = timeout; return this.cmd.ExecuteReader(behavior); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">读取类型(sql文本,存储过程,表)</param> /// <param name="behavior">提供了一个查询的结果的描述和对数据库的影响</param> /// <returns>IDataReader</returns> protected IDataReader ExecuteReader(string sql, CommandType type, CommandBehavior behavior) { return this.ExecuteReader(sql, type, behavior, 0); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">读取类型(sql文本,存储过程,表)</param> /// <param name="timeout">超时时间</param> /// <returns>IDataReader</returns> protected IDataReader ExecuteReader(string sql, CommandType type, int timeout) { return this.ExecuteReader(sql, type, CommandBehavior.Default, timeout); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">读取类型(sql文本,存储过程,表)</param> /// <returns>IDataReader</returns> protected IDataReader ExecuteReader(string sql, CommandType type) { return this.ExecuteReader(sql, type, CommandBehavior.Default, 0); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="behavior">提供了一个查询的结果的描述和对数据库的影响</param> /// <param name="timeout">超时时间</param> /// <returns>IDataReader</returns> protected IDataReader ExecuteReader(string sql, CommandBehavior behavior, int timeout) { return this.ExecuteReader(sql, CommandType.Text, behavior, timeout); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="behavior">提供了一个查询的结果的描述和对数据库的影响</param> /// <returns>IDataReader</returns> protected IDataReader ExecuteReader(string sql, CommandBehavior behavior) { return this.ExecuteReader(sql, CommandType.Text, behavior, 0); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="timeout">超时时间</param> /// <returns>IDataReader</returns> protected IDataReader ExecuteReader(string sql, int timeout) { return this.ExecuteReader(sql, CommandType.Text, CommandBehavior.Default, timeout); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <returns>IDataReader</returns> protected IDataReader ExecuteReader(string sql) { return this.ExecuteReader(sql, CommandType.Text, CommandBehavior.Default, 0); } #endregion #region ExecuteTable /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">读取类型(sql文本,存储过程,表)</param> /// <param name="behavior">提供了一个查询的结果的描述和对数据库的影响</param> /// <param name="timeout">超时时间</param> /// <returns>DataTable</returns> protected DataTable ExecuteTable(string sql, CommandType type, CommandBehavior behavior, int timeout) { using (IDataReader dr = this.ExecuteReader(sql, type, behavior, timeout)) { DataTable dt = new DataTable(); dt.Load(dr); return dt; } } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">读取类型(sql文本,存储过程,表)</param> /// <param name="behavior">提供了一个查询的结果的描述和对数据库的影响</param> /// <returns>DataTable</returns> protected DataTable ExecuteTable(string sql, CommandType type, CommandBehavior behavior) { return this.ExecuteTable(sql, type, behavior, 0); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">读取类型(sql文本,存储过程,表)</param> /// <param name="timeout">超时时间</param> /// <returns>DataTable</returns> protected DataTable ExecuteTable(string sql, CommandType type, int timeout) { return this.ExecuteTable(sql, type, CommandBehavior.Default, timeout); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">读取类型(sql文本,存储过程,表)</param> /// <returns>DataTable</returns> protected DataTable ExecuteTable(string sql, CommandType type) { return this.ExecuteTable(sql, type, CommandBehavior.Default, 0); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="behavior">提供了一个查询的结果的描述和对数据库的影响</param> /// <param name="timeout">超时时间</param> /// <returns>DataTable</returns> protected DataTable ExecuteTable(string sql, CommandBehavior behavior, int timeout) { return this.ExecuteTable(sql, CommandType.Text, behavior, timeout); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="behavior">提供了一个查询的结果的描述和对数据库的影响</param> /// <returns>DataTable</returns> protected DataTable ExecuteTable(string sql, CommandBehavior behavior) { return this.ExecuteTable(sql, CommandType.Text, behavior, 0); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="timeout">超时时间</param> /// <returns>DataTable</returns> protected DataTable ExecuteTable(string sql, int timeout) { return this.ExecuteTable(sql, CommandType.Text, CommandBehavior.Default, timeout); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <returns>DataTable</returns> protected DataTable ExecuteTable(string sql) { return this.ExecuteTable(sql, CommandType.Text, CommandBehavior.Default, 0); } #endregion #region ExecuteDataSet /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="tableName">表名</param> /// <returns>DataTable</returns> protected DataSet ExecuteDataSet(string sql, params string[] tableName) { return this.ExecuteDataSet(sql, CommandType.Text, tableName); } /// <summary> /// 读取数据 /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">读取类型</param> /// <param name="tableName">表名</param> /// <returns>DataTable</returns> protected DataSet ExecuteDataSet(string sql, CommandType type, params string[] tableName) { using (IDataReader dr = this.ExecuteReader(sql, type, CommandBehavior.Default, 0)) { DataSet ds = new DataSet(); ds.Load(dr, LoadOption.Upsert, tableName); return ds; } } #endregion #region ExecuteScalar /// <summary> /// ExecuteScalar /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">执行类型</param> /// <param name="timeout">超时时间</param> /// <returns>结果</returns> protected object ExecuteScalar(string sql, CommandType type, int timeout) { if (string.IsNullOrWhiteSpace(sql)) { throw new ArgumentNullException("sql"); } this.cmd.CommandText = sql; this.cmd.CommandType = type; this.cmd.CommandTimeout = timeout; object result = this.cmd.ExecuteScalar(); return result == DBNull.Value ? null : result; } /// <summary> /// ExecuteScalar /// </summary> /// <param name="sql">sql语句</param> /// <returns>结果</returns> protected object ExecuteScalar(string sql) { return this.ExecuteScalar(sql, CommandType.Text, 0); } #endregion #region ExecuteNonQuery /// <summary> /// ExecuteNonQuery /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">执行类型</param> /// <param name="timeout">超时时间</param> /// <returns>结果</returns> protected int ExecuteNonQuery(string sql, CommandType type, int timeout) { if (string.IsNullOrWhiteSpace(sql)) { throw new ArgumentNullException("sql"); } this.cmd.CommandText = sql; this.cmd.CommandType = type; this.cmd.CommandTimeout = timeout; return this.cmd.ExecuteNonQuery(); } /// <summary> /// ExecuteNonQuery /// </summary> /// <param name="sql">sql语句</param> /// <param name="type">执行类型</param> /// <returns>结果</returns> protected int ExecuteNonQuery(string sql, CommandType type) { return this.ExecuteNonQuery(sql, type, 0); } /// <summary> /// ExecuteNonQuery /// </summary> /// <param name="sql">sql语句</param> /// <param name="timeout">超时时间</param> /// <returns>结果</returns> protected int ExecuteNonQuery(string sql, int timeout) { return this.ExecuteNonQuery(sql, CommandType.Text, timeout); } /// <summary> /// ExecuteNonQuery /// </summary> /// <param name="sql">sql语句</param> /// <returns>结果</returns> protected int ExecuteNonQuery(string sql) { return this.ExecuteNonQuery(sql, CommandType.Text, 0); } #endregion #region CreateParameter /// <summary> /// 创建参数 /// </summary> /// <param name="name">参数名称</param> /// <returns>参数</returns> private IDbDataParameter CreateParameter(string name) { IDbDataParameter param = this.cmd.CreateParameter(); param.ParameterName = name; return param; } /// <summary> /// 创建参数 /// </summary> /// <param name="name">参数名称</param> /// <param name="value">参数值</param> /// <returns>参数</returns> private IDbDataParameter CreateParameter(string name, object value) { IDbDataParameter param = this.CreateParameter(name); param.Value = value ?? DBNull.Value; return param; } /// <summary> /// 创建参数 /// </summary> /// <param name="name">参数名称</param> /// <param name="value">参数值</param> /// <param name="type">参数类型</param> /// <returns>参数</returns> private IDbDataParameter CreateParameter(string name, object value, DbType type) { IDbDataParameter param = this.CreateParameter(name, value); param.DbType = type; return param; } /// <summary> /// 创建参数 /// </summary> /// <param name="name">参数名称</param> /// <param name="value">参数值</param> /// <param name="type">参数类型</param> /// <param name="direction">参数输出类型</param> /// <returns>参数</returns> private IDbDataParameter CreateParameter(string name, object value, DbType type, ParameterDirection direction) { IDbDataParameter param = this.CreateParameter(name, value, type); param.Direction = direction; return param; } /// <summary> /// 创建参数 /// </summary> /// <param name="name">参数名称</param> /// <param name="value">参数值</param> /// <param name="type">参数类型</param> /// <param name="direction">参数输出类型</param> /// <param name="size">参数大小</param> /// <returns>参数</returns> private IDbDataParameter CreateParameter(string name, object value, DbType type, ParameterDirection direction, int size) { IDbDataParameter param = this.CreateParameter(name, value, type, direction); param.Size = size; return param; } /// <summary> /// 创建参数 /// </summary> /// <param name="name">参数名称</param> /// <param name="value">参数值</param> /// <param name="type">参数类型</param> /// <param name="direction">参数输出类型</param> /// <param name="size">参数大小</param> /// <param name="scale">显示数字参数的规模(精确到小数点后几位)</param> /// <returns>参数</returns> private IDbDataParameter CreateParameter(string name, object value, DbType type, ParameterDirection direction, int size, byte scale) { IDbDataParameter param = this.CreateParameter(name, value, type, direction, size); param.Scale = scale; return param; } #endregion /// <summary> /// 释放资源 /// </summary> public void Dispose() { if (this.cmd != null) { this.cmd.Dispose(); this.cmd = null; } if (this.connection == null) { return; } if (this.connection.State == ConnectionState.Open) { this.connection.Close(); } this.connection.Dispose(); this.connection = null; } } }
IRepository (Code)
using Notify.Infrastructure.DomainBase; namespace Notify.Infrastructure.RepositoryFramework { /// <summary> /// 仓储接口(CRUD) /// </summary> /// <typeparam name="TValue">实体</typeparam> public interface IRepository<TValue> : IAddRepository<TValue>, IRemoveRepository<TValue>, IUpdateRepository<TValue>, IQueryRepository<TValue> where TValue : IEntity { } /// <summary> /// 仓储接口(CRUD) /// </summary> /// <typeparam name="TKey">主键</typeparam> /// <typeparam name="TValue">实体</typeparam> public interface IRepository<in TKey, TValue> : IAddRepository<TValue>, IRemoveRepository<TValue>, IUpdateRepository<TValue>, IQueryRepository<TKey, TValue> where TValue : IEntity { } }
IUnitOfWorkRepository (Code)
using Notify.Infrastructure.DomainBase; namespace Notify.Infrastructure.RepositoryFramework { /// <summary> /// 工作单元仓储接口 /// </summary> public interface IUnitOfWorkRepository { /// <summary> /// 持久化新增实体 /// </summary> /// <param name="item">待新增实体接口</param> void PersistNewItem(IEntity item); /// <summary> /// 持久化更新实体 /// </summary> /// <param name="item">待更新实体接口</param> void PersistUpdatedItem(IEntity item); /// <summary> /// 持久化删除实体 /// </summary> /// <param name="item">待删除实体接口</param> void PersistDeletedItem(IEntity item); } }
UnitOfWorkRepositoryBase (Code)
using Notify.Infrastructure.DomainBase; using Notify.Infrastructure.RepositoryFramework; using Notify.Infrastructure.UnitOfWork; namespace Notify.DbCommon.Repositroies { /// <summary> /// 工作单元仓储基类 /// </summary> /// <typeparam name="TKey">主键</typeparam> /// <typeparam name="TValue">实体</typeparam> public abstract class UnitOfWorkRepositoryBase<TKey, TValue> : BaseRepository, IRepository<TKey, TValue>, IUnitOfWorkRepository where TValue : IEntity { /// <summary> /// 工作单元接口 /// </summary> public new IPowerUnitOfWork UnitOfWork { get; private set; } /// <summary> /// Initializes a new instance of the <see cref="UnitOfWorkRepositoryBase{TKey,TValue}"/> class. /// 构造函数 /// </summary> /// <param name="unitOfWork">工作单元</param> /// <param name="name">数据连接</param> protected UnitOfWorkRepositoryBase(IPowerUnitOfWork unitOfWork, string name) : base(unitOfWork, name) { this.UnitOfWork = unitOfWork; } /// <summary> /// 根据主键查询实体 /// </summary> /// <param name="key">主键</param> /// <returns>实体</returns> public abstract TValue Query(TKey key); /// <summary> /// 根据主键查询实体(索引) /// </summary> /// <param name="key">主键</param> /// <returns>实体</returns> public TValue this[TKey key] { get { return this.Query(key); } set { if (this.Query(key) == null) { this.Add(value); } else { this.Update(value); } } } /// <summary> /// 添加实体(注册到工作单元) /// </summary> /// <param name="item">实体</param> public void Add(TValue item) { if (this.UnitOfWork != null) { this.UnitOfWork.RegisterAdded(item, this); } else { this.PersistNewItem(item); } } /// <summary> /// 删除实体(注册到工作单元) /// </summary> /// <param name="item">实体</param> public void Remove(TValue item) { if (this.UnitOfWork != null) { this.UnitOfWork.RegisterRemoved(item, this); } else { this.PersistDeletedItem(item); } } /// <summary> /// 修改实体(注册到工作单元) /// </summary> /// <param name="item">实体</param> public void Update(TValue item) { if (this.UnitOfWork != null) { this.UnitOfWork.RegisterChanged(item, this); } else { this.PersistUpdatedItem(item); } } /// <summary> /// 添加实体(持久化) /// </summary> /// <param name="item">实体</param> public abstract void PersistNewItem(IEntity item); /// <summary> /// 修改实体(持久化) /// </summary> /// <param name="item">实体</param> public abstract void PersistUpdatedItem(IEntity item); /// <summary> /// 删除实体(持久化) /// </summary> /// <param name="item">实体</param> public abstract void PersistDeletedItem(IEntity item); } }
SqlRepositoryBase (Code)
using System.Collections.Generic; using System.Data; using System.Linq; using Notify.Infrastructure.DomainBase; using Notify.Infrastructure.EntityFactoryFramework; using Notify.Infrastructure.UnitOfWork; namespace Notify.DbCommon.Repositroies { /// <summary> /// 工作单元仓储基类 /// </summary> /// <typeparam name="TKey">主键</typeparam> /// <typeparam name="TValue">实体</typeparam> public abstract class SqlRepositoryBase<TKey, TValue> : UnitOfWorkRepositoryBase<TKey, TValue> where TValue : IEntity { /// <summary> /// 有子对象的回调委托 /// </summary> /// <param name="entityAggregate">实体聚合根</param> /// <param name="childEntityKeyValue">子实体键</param> public delegate void AppendChildData(TValue entityAggregate, object childEntityKeyValue); /// <summary> /// 实体工厂 /// </summary> protected readonly IEntityFactory<TValue> m_entityFactory; /// <summary> /// 子对象集 /// </summary> private readonly Dictionary<string, AppendChildData> m_childCallbacks; /// <summary> /// 子对象数据集 /// </summary> private readonly Dictionary<string, object> m_childKeyDatas; /// <summary> /// 构造函数 /// </summary> /// <param name="unitOfWork">工作单元</param> /// <param name="name">数据连接</param> protected SqlRepositoryBase(IPowerUnitOfWork unitOfWork, string name) : base(unitOfWork, name) { this.m_entityFactory = this.BuildEntityFactory(); this.m_childCallbacks = new Dictionary<string, AppendChildData>(); this.m_childKeyDatas = new Dictionary<string, object>(); this.BuildChildCallbacks(this.m_childCallbacks); } /// <summary> /// 改为由子类创建实体,不使用工厂 /// </summary> /// <returns>TValue</returns> protected abstract IEntityFactory<TValue> BuildEntityFactory(); /// <summary> /// 创建子对象回调 /// </summary> /// <param name="childCallbacks">子对象集</param> protected abstract void BuildChildCallbacks(Dictionary<string, AppendChildData> childCallbacks); /// <summary> /// 子对象回调集 /// </summary> protected Dictionary<string, AppendChildData> ChildCallbacks { get { return this.m_childCallbacks; } } /// <summary> /// 创建实体对象 /// </summary> /// <param name="reader">IDataReader</param> /// <returns>实体对象</returns> protected virtual TValue BuildEntityFromReader(IDataReader reader) { TValue entity = this.m_entityFactory.BuildEntity(reader); if (this.m_childCallbacks != null && this.m_childCallbacks.Count > 0) { DataTable columnData = reader.GetSchemaTable(); foreach (string childKeyName in this.m_childCallbacks.Keys) { object childKeyValue; ////判断 DataReader 的数据集合中是否存在一个特定的列名(或字段名) if (columnData != null && columnData.Rows.Cast<DataRow>().Any(row => row["ColumnName"].ToString() == childKeyName)) { childKeyValue = reader[childKeyName]; } else { childKeyValue = null; } if (m_childKeyDatas.ContainsKey(childKeyName)) { m_childKeyDatas[childKeyName] = childKeyValue; } else { m_childKeyDatas.Add(childKeyName, childKeyValue); } } } return entity; } /// <summary> /// 创建实体对象 /// </summary> /// <param name="sql">sql语句</param> /// <returns>实体对象</returns> protected virtual TValue BuildEntityFromSql(string sql) { TValue entity = default(TValue); using (IDataReader reader = this.ExecuteReader(sql)) { if (reader.Read()) { entity = this.BuildEntityFromReader(reader); } } if (entity != null) { this.InvokeChildCallbacks(entity); } return entity; } /// <summary> /// 创建实体对象集合 /// </summary> /// <param name="sql">sql语句</param> /// <returns>实体对象集合</returns> protected virtual List<TValue> BuildEntitiesFromSql(string sql) { List<TValue> entities = new List<TValue>(); using (IDataReader reader = this.ExecuteReader(sql)) { while (reader.Read()) { entities.Add(this.BuildEntityFromReader(reader)); } } return entities; } /// <summary> /// 加载子对象 /// </summary> /// <param name="entity">实体对象</param> private void InvokeChildCallbacks(TValue entity) { if (this.m_childCallbacks != null && this.m_childCallbacks.Any()) { foreach (string childKeyName in this.m_childKeyDatas.Keys) { object childKeyValue; this.m_childKeyDatas.TryGetValue(childKeyName, out childKeyValue); this.m_childCallbacks[childKeyName](entity, childKeyValue); } } } } }
Repository(Code):
该层代码将再后面文章讲解