zoukankan      html  css  js  c++  java
  • DataReader扩展方法

      1 using System; 
      2 using System.Collections.Generic; 
      3 using System.Data;
      4 using System.Diagnostics; 
      5 using System.Linq; 
      6 using System.Linq.Expressions; 
      7 using System.Reflection;
      8 using System.ComponentModel;
      9 
     10 public static class DataReaderExtensions
     11 {
     12     #region Private Methods
     13     private static readonly Dictionary<Type, Delegate> cache = new Dictionary<Type, Delegate>();
     14     private static readonly object cacheLocker = new object();
     15     #endregion
     16 
     17     public static T Field<T>(this IDataReader reader, string name)
     18     {
     19         return reader[name].ConvertTo<T>(default(T), false);
     20     }
     21 
     22 
     23     public static T Field<T>(this IDataReader reader, int index)
     24     {
     25         return reader[index].ConvertTo<T>(default(T), false);
     26     }
     27 
     28     public static List<T> ToList<T>(this IDataReader reader) where T : class, new()
     29     {
     30         return Fill<T>(reader, DynamicCreateEntity<T>()).ToList();
     31     }
     32 
     33     public static List<T> ToList<T>(this IDataReader reader, Func<IDataReader, T> predicate) where T : class, new()
     34     {
     35         return Fill<T>(reader, predicate).ToList();
     36     }
     37 
     38     private static Func<IDataReader, T> DynamicCreateEntity<T>() where T : class, new()
     39     {
     40         var type = typeof(T); 
     41         if (cache.ContainsKey(type))
     42             return (Func<IDataReader, T>)cache[type];
     43         lock (cacheLocker)
     44         {
     45             if (cache.ContainsKey(type))
     46                 return (Func<IDataReader, T>)cache[type];
     47             var result = DynamicCreateEntityLogic<T>(); 
     48             cache.Add(type, result); 
     49             return result;
     50         }
     51     }
     52 
     53     private static Func<IDataReader, T> DynamicCreateEntityLogic<T>() where T : class, new()
     54     {
     55         // Compiles a delegate of the form (IDataReader r) => new T { Prop1 = r.Field<Prop1Type>("Prop1"), ... }            
     56         ParameterExpression r = Expression.Parameter(typeof(IDataReader), "r");
     57         // Get Properties of the property can read and write             
     58         var props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite).ToArray();
     59         // Create property bindings for all writable properties             
     60         List<MemberBinding> bindings = new List<MemberBinding>(props.Length);
     61         // Get the binding method             
     62         var method = typeof(DataReaderExtensions).GetMethods().First(p =>
     63             p.Name == "Field" &&
     64             p.GetParameters().Length == 2 &&
     65             p.GetParameters()[1].ParameterType == typeof(string));
     66         foreach (PropertyInfo property in (typeof(T).GetProperties()))
     67         {
     68             // Create expression representing r.Field<property.PropertyType>(property.Name)                 
     69             MethodCallExpression propertyValue = Expression.Call(method.MakeGenericMethod(property.PropertyType), r, Expression.Constant(property.Name));
     70             // Assign the property value to property through a member binding                 
     71             MemberBinding binding = Expression.Bind(property, propertyValue);
     72             bindings.Add(binding);
     73         }
     74         // Create the initializer, which instantiates an instance of T and sets property values               
     75         // using the member bindings we just created             
     76         Expression initializer = Expression.MemberInit(Expression.New(typeof(T)), bindings);
     77         // Create the lambda expression, which represents the complete delegate (r => initializer)  
     78         Expression<Func<IDataReader, T>> lambda = Expression.Lambda<Func<IDataReader, T>>(initializer, r);
     79         return lambda.Compile();
     80     }
     81 
     82     private static IEnumerable<T> Fill<T>(IDataReader reader, Func<IDataReader, T> predicate) where T : class, new()
     83     {
     84         while (reader.Read())
     85             yield return predicate(reader);
     86     }
     87 }
     88 
     89 public static class ExtensionMethod
     90 {
     91     private static string typeIConvertibleFullName = typeof(IConvertible).FullName;
     92     public static T ConvertTo<T>(this object obj, T defaultValue)
     93     {
     94         if (obj != null)
     95         {
     96             if (obj is T)
     97                 return (T)obj;
     98             var sourceType = obj.GetType();
     99             var targetType = typeof(T);
    100             if (targetType.IsEnum)
    101                 return (T)Enum.Parse(targetType, obj.ToString(), true);
    102             if (sourceType.GetInterface(typeIConvertibleFullName) != null &&
    103             targetType.GetInterface(typeIConvertibleFullName) != null)
    104                 return (T)Convert.ChangeType(obj, targetType);
    105             var converter = TypeDescriptor.GetConverter(obj);
    106             if (converter != null && converter.CanConvertTo(targetType))
    107                 return (T)converter.ConvertTo(obj, targetType);
    108             converter = TypeDescriptor.GetConverter(targetType);
    109             if (converter != null && converter.CanConvertFrom(sourceType))
    110                 return (T)converter.ConvertFrom(obj);
    111             throw new Exception("convert error.");
    112         }
    113         throw new ArgumentNullException("obj");
    114     }
    115 
    116 
    117     public static T ConvertTo<T>(this object obj)
    118     {
    119         return ConvertTo(obj, default(T));
    120     }
    121 
    122     public static T ConvertTo<T>(this object obj, T defaultValue, bool ignoreException)
    123     {
    124         if (ignoreException)
    125         {
    126             try
    127             {
    128                 return obj.ConvertTo<T>(defaultValue);
    129             }
    130             catch
    131             {
    132                 return defaultValue;
    133             }
    134         }
    135         return obj.ConvertTo<T>(defaultValue);
    136     }
    137 }

    ---------知其然更要知其所以然

  • 相关阅读:
    Python函数
    linux—shell 脚本编程
    python 内建函数
    列表解析式(List Comprehension)
    python标准库(datetime)
    python字典(dict)
    常用数据结构
    C 2010年笔试题
    C 2012年笔试题(保)
    C 2012年笔试题
  • 原文地址:https://www.cnblogs.com/netqiang/p/3248760.html
Copyright © 2011-2022 走看看