Esempio n. 1
0
        /// <summary>
        ///     Query IEnumerable<T> by sql
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="context"></param>
        /// <param name="sql"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static IEnumerable <T> Query <T>(this IRepositoryContext context, string sql, params object[] args)
            where T : new()
        {
            using (var dr = context.ExecuteDataReader(sql)) {
                if (dr.HasRows)
                {
                    var propCache = new Dictionary <string, PropertyInfo>();
                    var drFields  = new List <string>();
                    for (var i = 0; i < dr.FieldCount; i++)
                    {
                        drFields.Add(dr.GetName(i));
                    }

                    while (dr.Read())
                    {
                        var insT = new T();
                        if (propCache.Count == drFields.Count)
                        {
                            var propList = insT.GetType().GetProperties();
                            foreach (var field in drFields)
                            {
                                var prop  = propCache[field];
                                var value = dr[field];
                                if (value != DBNull.Value)
                                {
                                    prop.SetValue(insT, value, null);
                                }
                            }
                        }
                        else
                        {
                            var propList = insT.GetType().GetProperties();
                            foreach (var prop in propList)
                            {
                                var field = prop.Name;
                                if (!drFields.Contains(field))
                                {
                                    continue;
                                }

                                if (!prop.CanWrite)
                                {
                                    continue;
                                }

                                var value = dr[field];
                                if (value != DBNull.Value)
                                {
                                    prop.SetValue(insT, value, null);
                                }

                                if (!propCache.ContainsKey(field))
                                {
                                    propCache.Add(field, prop);
                                }
                            }

                            // Re-balance PropCache & drFields
                            if (propCache.Count != drFields.Count)
                            {
                                var interset = drFields.Intersect(propCache.Select(x => x.Key)).ToList();
                                drFields = interset;

                                var subSet = propCache.Select(x => x.Key).Except(interset);
                                foreach (var item in subSet)
                                {
                                    propCache.Remove(item);
                                }
                            }
                        }

                        yield return(insT);
                    }
                }
            }
        }