/// <summary> /// 将 <see cref="IDataRecord"/> 映射为实体 /// </summary> /// <typeparam reader="T">数据源</typeparam> /// <param name="reader">数据源</param> /// <param name="define">命令定义</param> /// <returns></returns> public static T ToModel <T>(this IDataRecord reader, CommandDefine define = null) { object obj = null; object[] values = null; int index = 0; // 基元类初始化 ######################## if (Reflection.TypeUtils.IsPrimitive(typeof(T))) { //if(reader.IsDBNull(0)) return default(T) //obj = reader.GetValue(0); //return obj is DBNull ? default(T) : (T)obj; return(reader.IsDBNull(0) ? default(T) : (T)reader.GetValue(0)); } // 匿名类初始化 ######################## TypeRuntimeInfo runtime = TypeRuntimeInfoCache.GetRuntimeInfo <T>(); Inte.XFramework.Reflection.Emit.ConstructorInvoker ctor = runtime.ConstructInvoker; if (runtime.IsAnonymousType) { values = new object[reader.FieldCount]; reader.GetValues(values); for (index = 0; index < values.Length; ++index) { if (values[index] is DBNull) { values[index] = null; } } return((T)ctor.Invoke(values)); } // 实体类初始化 ######################## T model = (T)ctor.Invoke(); values = new object[reader.FieldCount]; reader.GetValues(values); // 计算导航属性所占用的索引,这些索引对应的值不会赋给 T 实体 var sc = define as CommandDefine_Select; if (sc == null || (sc.NavDescriptors != null && sc.NavDescriptors.Count == 0)) { // 直接跑SQL,则不解析导航属性 for (int i = 0; i < reader.FieldCount; ++i) { obj = values[i]; if (obj == DBNull.Value) { continue; } string name = reader.GetName(i); var wrapper = runtime.GetWrapper(name) as MemberAccessWrapper; if (wrapper != null) { SetProperty(model, wrapper, obj); } } } else { // 使用表达式查询,解析导航属性 bool nav = sc.NavDescriptors.Any(x => x.Value.Count > 0); int min = nav ? sc.NavDescriptors.Min(x => x.Value.Start) : 0; // 第一层 index = -1; foreach (var kvp in sc.Columns) { index += 1; obj = values[index]; if (obj == DBNull.Value) { continue; } if (nav && index >= min) { break; } var wrapper = runtime.GetWrapper(kvp.Value.Name) as MemberAccessWrapper; if (wrapper != null) { SetProperty(model, wrapper, obj); } } // 递归导航属性 if (runtime.NavWrappers.Count > 0) { ToModel_Navigation(model, values, sc, string.Empty); } } return(model); }
/// <summary> /// 将 <see cref="IDataRecord"/> 上的当前行反序列化为实体 /// </summary> /// <returns></returns> public T Deserialize() { #region 基元类型 if (Reflection.TypeUtils.IsPrimitive(typeof(T))) { if (_reader.IsDBNull(0)) { return(default(T)); } var obj = _reader.GetValue(0); if (obj.GetType() != typeof(T)) { obj = Convert.ChangeType(obj, typeof(T)); } return((T)obj); } #endregion #region 匿名类型 TypeRuntimeInfo runtime = TypeRuntimeInfoCache.GetRuntimeInfo <T>(); Inte.XFramework.Reflection.Emit.ConstructorInvoker ctor = runtime.ConstructInvoker; if (runtime.IsAnonymousType) { object[] values = new object[_reader.FieldCount]; _reader.GetValues(values); for (int index = 0; index < values.Length; ++index) { if (values[index] is DBNull) { values[index] = null; } } return((T)ctor.Invoke(values)); } #endregion #region 实体类型 T model = default(T); if (_define == null || (_define.NavDescriptors != null && _define.NavDescriptors.Count == 0)) { // 直接跑SQL,则不解析导航属性 if (_topLevel == null) { _topLevel = GetDeserializer(typeof(T), _reader); } model = (T)_topLevel(_reader); } else { // 第一层 if (_topLevel == null) { _topLevel = GetDeserializer(typeof(T), _reader, _define.Columns, 0, _define.NavDescriptors.MinIndex); } model = (T)_topLevel(_reader); // 递归导航属性 this.Deserialize_Navigation(model, string.Empty); } #endregion return(model); }