Created
March 19, 2013 13:16
-
-
Save joshgo/5196023 to your computer and use it in GitHub Desktop.
Simple reader extensions. Converts reader records into Entities/Objects - Support for simple types
- And just dabbling with Expression Trees
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Linq.Expressions; | |
| using System.Reflection; | |
| using System.Text; | |
| namespace ReaderExtensions.Extensions | |
| { | |
| public static class DataReaderExtensions | |
| { | |
| private static readonly Dictionary<Type, Delegate> _initializers = new Dictionary<Type, Delegate>(); | |
| public static T GetRow<T>(this System.Data.IDataReader reader) | |
| { | |
| var type = typeof(T); | |
| if(!_initializers.ContainsKey(type)) | |
| _initializers.Add(type, GetInitializers<T>(reader)); | |
| return ((Func<System.Data.IDataReader, T>)_initializers[type])(reader); | |
| } | |
| private static Func<System.Data.IDataReader, T> GetInitializers<T>(System.Data.IDataReader reader) | |
| { | |
| var t_type = typeof(T); | |
| var t_IDataRecord = typeof(System.Data.IDataRecord); | |
| var t_this = typeof(DataReaderExtensions); | |
| ParameterExpression readerParam = Expression.Parameter(typeof(System.Data.IDataReader), "reader"); | |
| List<MemberBinding> bindings = new List<MemberBinding>(); | |
| Dictionary<string, int> indexes = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); | |
| Dictionary<Type, string> readerMethods = new Dictionary<Type, string>(); | |
| Dictionary<Type, string> nullableMethods = new Dictionary<Type, string>(); | |
| for (int i = 0; i < reader.FieldCount; i++) | |
| indexes.Add(reader.GetName(i), i); | |
| readerMethods.Add(typeof(bool), "GetBoolean"); | |
| readerMethods.Add(typeof(byte), "GetByte"); | |
| readerMethods.Add(typeof(char), "GetChar"); | |
| readerMethods.Add(typeof(DateTime), "GetDateTime"); | |
| readerMethods.Add(typeof(decimal), "GetDecimal"); | |
| readerMethods.Add(typeof(double), "GetDouble"); | |
| readerMethods.Add(typeof(float), "GetFloat"); | |
| readerMethods.Add(typeof(Guid), "GetGuid"); | |
| readerMethods.Add(typeof(Int32), "GetInt32"); | |
| readerMethods.Add(typeof(Int16), "GetInt16"); | |
| readerMethods.Add(typeof(Int64), "GetInt64"); | |
| readerMethods.Add(typeof(object), "GetValue"); | |
| readerMethods.Add(typeof(string), "GetString"); | |
| nullableMethods.Add(typeof(Int16?), "GetNullableInt16"); | |
| nullableMethods.Add(typeof(Int32?), "GetNullableInt32"); | |
| nullableMethods.Add(typeof(Int64?), "GetNullableInt64"); | |
| foreach (var p in t_type.GetProperties()) | |
| { | |
| Expression fieldExpression = null; | |
| if (readerMethods.ContainsKey(p.PropertyType)) | |
| { | |
| var method = t_IDataRecord.GetMethod(readerMethods[p.PropertyType], new[] { typeof(int) }); | |
| fieldExpression = Expression.Call(readerParam, method, Expression.Constant(indexes[p.Name], typeof(int))); | |
| } | |
| else if (nullableMethods.ContainsKey(p.PropertyType)) | |
| { | |
| var method = t_this.GetMethod(nullableMethods[p.PropertyType], new[] { typeof(System.Data.IDataReader), typeof(int) }); | |
| fieldExpression = Expression.Call(method, readerParam, Expression.Constant(indexes[p.Name], typeof(int))); | |
| } | |
| bindings.Add(Expression.Bind(p, fieldExpression)); | |
| } | |
| var memberInit = Expression.MemberInit(Expression.New(typeof(T)), bindings); | |
| var initializationLambda = Expression.Lambda<Func<System.Data.IDataReader, T>>(memberInit, readerParam); | |
| return initializationLambda.Compile(); | |
| } | |
| private static Expression SetFieldFromMethod(Type type, string methodName, ParameterExpression readerParam, int index) | |
| { | |
| var method = type.GetMethod(methodName, new[] { typeof(System.Data.IDataReader), typeof(int) }); | |
| return Expression.Call(method, readerParam, Expression.Constant(index)); | |
| } | |
| public static int? GetNullableInt16(this System.Data.IDataReader reader, int index) | |
| { | |
| Int16 val; | |
| if (Int16.TryParse(reader.GetString(index), out val)) | |
| return val; | |
| return null; | |
| } | |
| public static Int32? GetNullableInt32(this System.Data.IDataReader reader, int index) | |
| { | |
| Int32 val; | |
| if (Int32.TryParse(reader.GetString(index), out val)) | |
| return val; | |
| return null; | |
| } | |
| public static Int64? GetNullableInt64(this System.Data.IDataReader reader, int index) | |
| { | |
| Int64 val; | |
| if (Int64.TryParse(reader.GetString(index), out val)) | |
| return val; | |
| return null; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment