Example #1
0
        /// <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);
        }