zoukankan      html  css  js  c++  java
  • 用扩展方法来扩展IDataReader接口

    用扩展方法来扩展IDataReader接口

      实际应用中,有时我们需要用IDataReader来读取数据,或是填充对象,.c# 3.0的扩展方法可以用来扩展这个接口,以实现更方便的功能.以下有泛型方法,也有具体的方法,代码如下:

        9     /// <summary>
       10     /// Contains extension methods for the IDataReader interface.
       11     /// </summary>
       12     /// <remark>Author : PetterLiu 2009-04-17 22:34  http://wintersun.cnblogs.com </remark>
       13     public static class IDataReaderExtensions
       14     {
       15         /// <summary>
       16         /// Gets the IDataReader value.
       17         /// </summary>
       18         /// <typeparam name="T"></typeparam>
       19         /// <param name="reader">The reader.</param>
       20         /// <param name="fieldName">Name of the field.</param>
       21         /// <example><code>
       22         /// <![CDATA[
       23         ///   IDataReader reader = command.ExecuteReader();
       24         ///  if (reader.Read())
       25         ///  {
       26         ///    DateTime date = reader.GetValue<DateTime>("CreationDate");
       27         ///    Int32? orderId = reader.GetValue<Int32?>("NullableID");
       28         ///  }
       29         /// ]]>
       30         /// </code></example>
       31         /// <returns>The column value within the reader typed as T</returns>
       32         public static T GetValue<T>(this IDataReader reader, String fieldName)
       33         {
       34             if (String.IsNullOrEmpty(fieldName))
       35                 throw new ArgumentNullException("Field Name cannot be null");
       36             if (reader[fieldName] is DBNull)
       37                 return default(T);
       38             return (T)reader[fieldName];
       39         }
       40 
       41         /// <summary>
       42         /// Gets the value or default.
       43         /// </summary>
       44         /// <typeparam name="T"></typeparam>
       45         /// <param name="reader">The reader.</param>
       46         /// <param name="columnName">Name of the column.</param>
       47         /// <returns>The column value within the reader typed as T.</returns>
       48         /// <remark>PetterLiu 2009-04-17 22:34  http://wintersun.cnblogs.com </remark>
       49         /// <example><code>
       50         /// <![CDATA[
       51         /// int? myInt = reader.GetValueOrDefault<int?>("myColumnName");
       52         /// DateTime myDate = reader.GetValueOrDefault<DateTime>("myColumnName");
       53         /// ]]>
       54         /// </code></example>
       55         public static T GetValueOrDefault<T>(this IDataReader reader, string columnName)
       56         {
       57             return GetValueOrDefault<T>(reader, columnName, default(T));
       58         }
       59 
       60         /// <summary>
       61         /// Gets the value or default.
       62         /// </summary>
       63         /// <typeparam name="T"></typeparam>
       64         /// <param name="reader">The reader.</param>
       65         /// <param name="columnName">Name of the column.</param>
       66         /// <param name="defaultValue">The default value.</param>
       67         /// <returns>The column value within the reader typed as T.</returns>
       68         /// <remark>PetterLiu 2009-04-17 22:34  http://wintersun.cnblogs.com </remark>
       69         /// <example><code>
       70         /// <![CDATA[
       71         ///  //Default to true if myColumnName is null
       72         /// bool myBool = reader.GetValueOrDefault<bool>("myColumnName", true);
       73         /// ]]>
       74         /// </code></example>
       75         public static T GetValueOrDefault<T>(this IDataReader reader, string columnName, T defaultValue)
       76         {
       77             T returnValue = defaultValue;
       78             int ordinal;
       79             try
       80             {
       81                 ordinal = reader.GetOrdinal(columnName);
       82             }
       83             catch
       84             {
       85                 throw new Exception(string.Format("Column {0} was not found on IDataReader.", columnName));
       86             }
       87             object columnValue = reader.GetValue(ordinal);
       88             if (!(columnValue is DBNull))
       89             {
       90                 Type returnType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
       91                 returnValue = (T)Convert.ChangeType(columnValue, returnType);
       92             }
       93             return returnValue;
       94         }
       95 
       96         /// <summary>
       97         /// This method will return the value of the specified columnIndex, cast to
       98         /// the type specified in T.  However, if the value found in the reader is
       99         /// DBNull, this method will return the default value of the type T.
      100         /// </summary>
      101         /// <typeparam name="T">The type to which the value found in the reader should be cast.</typeparam>
      102         /// <param name="reader">The reader in which columnIndex exists.</param>
      103         /// <param name="columnName">The columnIndex to retrieve.</param>
      104         /// <returns>The column value within the reader typed as T.</returns>
      105         public static T GetValueOrDefault<T>(this IDataReader reader, int columnIndex)
      106         {
      107             return reader.GetValueOrDefault<T>(reader.GetName(columnIndex));
      108         }
      109 
      110 
      111         /// <summary>
      112         /// Gets the value.
      113         /// </summary>
      114         /// <typeparam name="T"></typeparam>
      115         /// <param name="reader">The reader.</param>
      116         /// <param name="field">The field.</param>
      117         /// <param name="code">The code.</param>
      118         /// <returns>The column value within the reader typed as T.</returns>
      119         /// <example><code>address.ID = dr.GetValue("ID", i => dr.GetInt32(i));</code></example>
      120         /// <remark>PetterLiu 2009-04-17 22:35  http://wintersun.cnblogs.com </remark>
      121         public static T GetValue<T>(this IDataReader reader, string field, Func<int, T> code)
      122         {
      123             T value = default(T);
      124             int ordinal = reader.GetOrdinal(field);
      125             if (!reader.IsDBNull(ordinal))
      126                 value = code(ordinal);
      127             return (value);
      128         }
      129 
      130         /// <summary>
      131         /// Gets the value or null.
      132         /// </summary>
      133         /// <typeparam name="T"></typeparam>
      134         /// <param name="reader">The reader.</param>
      135         /// <param name="field">The field.</param>
      136         /// <param name="code">The code.</param>
      137         /// <returns>The column value within the reader typed as T.</returns>
      138         /// <remark> PetterLiu 2009-04-17 22:38  http://wintersun.cnblogs.com </remark>
      139         public static T? GetValueOrNull<T>(this IDataReader reader, string field, Func<int, T> code) where T : struct
      140         {
      141             T? value = null;
      142             int ordinal = reader.GetOrdinal(field);
      143             if (!reader.IsDBNull(ordinal))
      144                 value = code(ordinal);
      145             return (value);
      146         }
      147 
      148 
      149         /// <summary>
      150         /// Returns a string if one is present, or null if not
      151         /// </summary>
      152         /// <param name="reader">The IDbReader to read from</param>
      153         /// <param name="index">The index of the column to read from</param>
      154         /// <returns>A string, or null if the column's value is NULL</returns>
      155         public static string GetNullableString(this IDataRecord reader, int index)
      156         {
      157             return reader.IsDBNull(index) ? (string)null : reader.GetString(index);
      158         }
      159 
      160         /// <summary>
      161         /// Returns a bool if one is present, or null if not
      162         /// </summary>
      163         /// <param name="reader">The IDbReader to read from</param>
      164         /// <param name="index">The index of the column to read from</param>
      165         /// <returns>A bool, or null if the column's value is NULL</returns>
      166         public static bool? GetNullableBool(this IDataRecord reader, int index)
      167         {
      168             return reader.IsDBNull(index) ? (bool?)null : reader.GetBoolean(index);
      169         }
      170 
      171         /// <summary>
      172         /// Returns a DateTime if one is present, or null if not
      173         /// </summary>
      174         /// <param name="reader">The IDbReader to read from</param>
      175         /// <param name="index">The index of the column to read from</param>
      176         /// <returns>A DateTime, or null if the column's value is NULL</returns>
      177         public static DateTime? GetNullableDateTime(this IDataRecord reader, int index)
      178         {
      179             return reader.IsDBNull(index) ? (DateTime?)null : reader.GetDateTime(index);
      180         }
      181 
      182         /// <summary>
      183         /// Returns a byte if one is present, or null if not
      184         /// </summary>
      185         /// <param name="reader">The IDbReader to read from</param>
      186         /// <param name="index">The index of the column to read from</param>
      187         /// <returns>A byte, or null if the column's value is NULL</returns>
      188         public static byte? GetNullableByte(this IDataRecord reader, int index)
      189         {
      190             return reader.IsDBNull(index) ? (byte?)null : reader.GetByte(index);
      191         }
      192 
      193         /// <summary>
      194         /// Returns a short if one is present, or null if not
      195         /// </summary>
      196         /// <param name="reader">The IDbReader to read from</param>
      197         /// <param name="index">The index of the column to read from</param>
      198         /// <returns>A short, or null if the column's value is NULL</returns>
      199         public static short? GetNullableInt16(this IDataRecord reader, int index)
      200         {
      201             return reader.IsDBNull(index) ? (short?)null : reader.GetInt16(index);
      202         }
      203 
      204         /// <summary>
      205         /// Returns an int if one is present, or null if not
      206         /// </summary>
      207         /// <param name="reader">The IDbReader to read from</param>
      208         /// <param name="index">The index of the column to read from</param>
      209         /// <returns>An int, or null if the column's value is NULL</returns>
      210         public static int? GetNullableInt32(this IDataRecord reader, int index)
      211         {
      212             return reader.IsDBNull(index) ? (int?)null : reader.GetInt32(index);
      213         }
      214 
      215         /// <summary>
      216         /// Returns a float if one is present, or null if not
      217         /// </summary>
      218         /// <param name="reader">The IDbReader to read from</param>
      219         /// <param name="index">The index of the column to read from</param>
      220         /// <returns>A float, or null if the column's value is NULL</returns>
      221         public static float? GetNullableFloat(this IDataRecord reader, int index)
      222         {
      223             return reader.IsDBNull(index) ? (float?)null : reader.GetFloat(index);
      224         }
      225 
      226         /// <summary>
      227         /// Returns a double if one is present, or null if not
      228         /// </summary>
      229         /// <param name="reader">The IDbReader to read from</param>
      230         /// <param name="index">The index of the column to read from</param>
      231         /// <returns>A double, or null if the column's value is NULL</returns>
      232         public static double? GetNullableDouble(this IDataRecord reader, int index)
      233         {
      234             return reader.IsDBNull(index) ? (double?)null : reader.GetDouble(index);
      235         }
      236 
      237     }

    几个测试的方法,以及另一个测试所用的扩展方法:

     12         /// <summary>
       13         /// Tests this instance.
       14         /// </summary>
       15         /// <remark>Author : PetterLiu 2009-04-18  0:07  http://wintersun.cnblogs.com </remark>
       16         public void Test()
       17         {
       18               var x = new Person[]
       19             {
       20                 new Person { Id = 1, Name = "Foo", Age = (int?)null },
       21                 new Person { Id = 2, Name = "Bar", Age = (int?)10 }
       22             };
       23               using (var r = x.ToDataReader())
       24               {
       25                   while (r.Read())
       26                   {
       27                       Console.WriteLine("{0}\t{1}\t{2}", r.GetInt32(0), r.GetString(1), r.GetNullableInt32(2));
       28                       Console.WriteLine("{0}\t{1}\t{2}", r.GetInt32(0), r.GetString(1), r.GetValue<int?>("Age"));
       29                       Console.WriteLine("{0}\t{1}\t{2}", r.GetInt32(0), r.GetString(1), r.GetValue("Age", i => r.GetInt32(i)));
       30                   }
       31               }
       32
       33             Console.Read();
       34         }
       35
       36         private class Person
       37         {
       38             public int Id { get; set; }
       39             public string Name { get; set; }
       40             public int? Age { get; set; }
       41         }

     62     public static class TestExtenstion
       63     {
       64         /// <summary>
       65         /// Returns an implementation of IDataReader based on the public properties of T,given an IEnumerable&lt;T&gt;
       66         /// </summary>
       67         /// <typeparam name="T">A type with properties from which to read</typeparam>
       68         /// <param name="items">A collection of instances of T</param>
       69         /// <returns>An implementation of IDataReader based on the public properties of T</returns>
       70         public static IDataReader ToDataReader<T>(this IEnumerable<T> items)
       71         {
       72             return new DataReader<T>(items);
       73         }
       74
       75
       76         /// <summary>
       77         /// Private implementation of IDataReader for an IEnumerable&lt;T&gt;
       78         /// </summary>
       79         /// <typeparam name="T">A type with properties from which to read</typeparam>
       80         private class DataReader<T> : IDataReader
       81         {
       82             public DataReader(IEnumerable<T> items)
       83             {
       84                 _enumerator = items.GetEnumerator();
       85
       86                 foreach (var prop in typeof(T).GetProperties())
       87                 {
       88                     _properties[prop.Name] = prop;
       89                 }
       90             }
       91
       92             private Dictionary<string, PropertyInfo> _properties
       93                 = new Dictionary<string, PropertyInfo>();
       94             private IEnumerator<T> _enumerator;
       95
       96             #region IDataReader Members
       97
       98             public void Close()
       99             {
      100             }
      101
      102             public int Depth
      103             {
      104                 get { return 0; }
      105             }
      106
      107             public DataTable GetSchemaTable()
      108             {
      109                 throw new NotImplementedException();
      110             }
      111
      112             public bool IsClosed
      113             {
      114                 get { return false; }
      115             }
      116
      117             public bool NextResult()
      118             {
      119                 return false;
      120             }
      121
      122             public bool Read()
      123             {
      124                 return _enumerator.MoveNext();
      125             }
      126
      127             public int RecordsAffected
      128             {
      129                 get { throw new NotImplementedException(); }
      130             }
      131
      132             #endregion
      133
      134             #region IDisposable Members
      135
      136             public void Dispose()
      137             {
      138             }
      139
      140             #endregion
      141
      142             #region IDataRecord Members
      143
      144             public int FieldCount
      145             {
      146                 get { return _properties.Count; }
      147             }
      148
      149             public bool GetBoolean(int i)
      150             {
      151                 return (bool)GetValue(i);
      152             }
      153
      154             public byte GetByte(int i)
      155             {
      156                 return (byte)GetValue(i);
      157             }
      158
      159             public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
      160             {
      161                 throw new NotImplementedException();
      162             }
      163
      164             public char GetChar(int i)
      165             {
      166                 return (char)GetValue(i);
      167             }
      168
      169             public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
      170             {
      171                 throw new NotImplementedException();
      172             }
      173
      174             public IDataReader GetData(int i)
      175             {
      176                 throw new NotImplementedException();
      177             }
      178
      179             public string GetDataTypeName(int i)
      180             {
      181                 var prop = _properties.Values.ToArray()[i];
      182                 return prop.PropertyType.ToString();
      183             }
      184
      185             public DateTime GetDateTime(int i)
      186             {
      187                 return (DateTime)GetValue(i);
      188             }
      189
      190             public decimal GetDecimal(int i)
      191             {
      192                 return (decimal)GetValue(i);
      193             }
      194
      195             public double GetDouble(int i)
      196             {
      197                 return (double)GetValue(i);
      198             }
      199
      200             public Type GetFieldType(int i)
      201             {
      202                 var prop = _properties.Values.ToArray()[i];
      203                 return prop.PropertyType;
      204             }
      205
      206             public float GetFloat(int i)
      207             {
      208                 return (float)GetValue(i);
      209             }
      210
      211             public Guid GetGuid(int i)
      212             {
      213                 return (Guid)GetValue(i);
      214             }
      215
      216             public short GetInt16(int i)
      217             {
      218                 return (short)GetValue(i);
      219             }
      220
      221             public int GetInt32(int i)
      222             {
      223                 return (int)GetValue(i);
      224             }
      225
      226             public long GetInt64(int i)
      227             {
      228                 return (long)GetValue(i);
      229             }
      230
      231             public string GetName(int i)
      232             {
      233                 return _properties.Keys.ToArray()[i];
      234             }
      235
      236             public int GetOrdinal(string name)
      237             {
      238                 return _properties.Keys.ToList().IndexOf(name);
      239             }
      240
      241             public string GetString(int i)
      242             {
      243                 return (string)GetValue(i);
      244             }
      245
      246             public object GetValue(int i)
      247             {
      248                 var prop = _properties.Values.ToArray()[i];
      249                 return prop.GetValue(_enumerator.Current, null);
      250             }
      251
      252             public int GetValues(object[] values)
      253             {
      254                 throw new NotImplementedException();
      255             }
      256
      257             public bool IsDBNull(int i)
      258             {
      259                 var prop = _properties.Values.ToArray()[i];
      260                 var val = prop.GetValue(_enumerator.Current, null);
      261                 return (val == null || val == DBNull.Value);
      262             }
      263
      264             public object this[string name]
      265             {
      266                 get
      267                 {
      268                     return _properties[name].GetValue(_enumerator.Current,
      269                         null);
      270                 }
      271             }
      272
      273             public object this[int i]
      274             {
      275                 get
      276                 {
      277                     var prop = _properties.Values.ToArray()[i];
      278                     return prop.GetValue(_enumerator.Current, null);
      279                 }
      280             }
      281
      282             #endregion
      283         }

    Author:  Petter Liu  ---  blog:     http://wintersun.cnblogs.com   
  • 相关阅读:
    # 抗战电视剧《河山》观后感 #
    SAP MM 自定义条件类型出现在采购信息记录的'条件'界面里 ?
    SAP 对HU做转库操作,系统报错
    SAP MM 采购订单与相关合同的价格差异问题分析
    2019年终总结之SAP项目实践篇
    大学教师,要做教授,请不要做叫兽!
    SAP MM 一个含有多个账号分配对象的行项目的PO及其收货
    华哥演技好!--- 电视剧《魔都风云》观后感
    SAP 如何看某个TR是否传入了Q或者P系统?
    Linux IO 模型
  • 原文地址:https://www.cnblogs.com/wintersun/p/1438738.html
Copyright © 2011-2022 走看看