/// <summary>
        /// 执行SQL 语句,并返回 <see cref="IEnumerable"/> 对象
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="query">SQL 命令</param>
        /// <param name="transaction">事务</param>
        /// <returns></returns>
        public List <T> ExecuteList <T>(IDbQueryable <T> query, IDbTransaction transaction = null)
        {
            CommandDefine define = this.Parse(query);
            IDbCommand    cmd    = this.CreateCommand(define.CommandText, transaction, define.CommandType, define.Parameters);

            return(this.ExecuteList <T>(cmd, define));
        }
        /// <summary>
        /// 执行SQL 语句,并返回单个实体对象
        /// </summary>
        /// <param name="cmd">SQL 命令</param>
        /// <param name="define">命令定义对象,用于解析实体的外键</param>
        /// <returns></returns>
        public T Execute <T>(IDbCommand cmd, CommandDefine define = null)
        {
            IDataReader   reader  = null;
            T             TResult = default(T);
            IDbConnection conn    = null;

            try
            {
                reader = this.ExecuteReader(cmd);
                conn   = cmd != null ? cmd.Connection : null;
                TypeDeserializer <T> deserializer = new TypeDeserializer <T>(reader, define as CommandDefine_Select);
                if (reader.Read())
                {
                    TResult = deserializer.Deserialize();
                }
                return(TResult);
            }
            finally
            {
                Dispose(cmd, reader, conn);
            }
        }
        /// <summary>
        /// 执行SQL 语句,并返回 <see cref="IEnumerable"/> 对象
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="cmd">SQL 命令</param>
        /// <param name="define">命令定义对象,用于解析实体的外键</param>
        /// <returns></returns>
        public List <T> ExecuteList <T>(IDbCommand cmd, CommandDefine define = null)
        {
            IDataReader   reader  = null;
            IDbConnection conn    = null;
            List <T>      objList = new List <T>();

            try
            {
                reader = this.ExecuteReader(cmd);
                conn   = cmd != null ? cmd.Connection : null;
                TypeDeserializer <T> deserializer = new TypeDeserializer <T>(reader, define as CommandDefine_Select);
                while (reader.Read())
                {
                    objList.Add(deserializer.Deserialize());
                }
                //yield return reader.ToEntity<T>();
            }
            finally
            {
                Dispose(cmd, reader, conn);
            }

            return(objList);
        }
Beispiel #4
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);
        }