Exemplo n.º 1
0
        // Generate a function (Func) that converts a row from the SqlDataReader into an object of type T,
        // using value conversion in the ValueFromDBConverter object.
        private static Func <ValueFromDBConverter, SqlDataReader, T> GenReader <T>(ValueFromDBConverter converter)
        {
            var dataReaderGetOrdinal = typeof(SqlDataReader).GetMethod(nameof(SqlDataReader.GetOrdinal), new[] { typeof(string) });
            var dataReaderGetValue   = typeof(SqlDataReader).GetMethod(nameof(SqlDataReader.GetValue), new[] { typeof(int) });
            var ctor       = typeof(T).GetConstructor(new Type[0]) ?? throw new ArgumentException("Type missing default constructor.");
            var properties = typeof(T).GetProperties()
                             .Where(p => Attribute.IsDefined(p, typeof(Column)));
            var dm = new DynamicMethod("Read" + typeof(T).Name, typeof(T),
                                       new[] { typeof(ValueFromDBConverter), typeof(SqlDataReader) });

            var gen = dm.GetILGenerator();

            gen.DeclareLocal(typeof(T));
            gen.DeclareLocal(typeof(int));
            gen.DeclareLocal(typeof(object));
            gen.Emit(OpCodes.Newobj, ctor); // push obj
            gen.Emit(OpCodes.Stloc_0);

            foreach (var property in properties)
            {
                var column     = (Column)Attribute.GetCustomAttribute(property, typeof(Column));
                var convMethod = converter.GetConvertMethod(property.PropertyType)
                                 ?? throw new ArgumentException("Unable to find converter for property.");
                var setter = property.GetSetMethod()
                             ?? throw new ArgumentException("Property missing setter.");
                gen.Emit(OpCodes.Ldarg_1);                        // SqlDataReader
                gen.Emit(OpCodes.Ldstr, column.Name);
                gen.Emit(OpCodes.Callvirt, dataReaderGetOrdinal); // dataReader.GetOrdinal
                gen.Emit(OpCodes.Stloc_1);

                gen.Emit(OpCodes.Ldarg_1);                      // SqlDataReader
                gen.Emit(OpCodes.Ldloc_1);
                gen.Emit(OpCodes.Callvirt, dataReaderGetValue); // dataReader.GetValue
                gen.Emit(OpCodes.Stloc_2);

                gen.Emit(OpCodes.Ldloc_0); // obj
                gen.Emit(OpCodes.Ldarg_0); // ValueFromDBConverter
                gen.Emit(OpCodes.Ldloc_2);
                //gen.Emit(OpCodes.Ldc_I4, (int)column.DbType);
                gen.Emit(OpCodes.Callvirt, convMethod); // converter.GetXxx(object value, int type)
                gen.Emit(OpCodes.Call, setter);         // obj.Property =
                // todo: cache ordinals for optimization
                // todo: gracefully handle missing properties
            }
            gen.Emit(OpCodes.Ldloc_0);
            gen.Emit(OpCodes.Ret);

            return((Func <ValueFromDBConverter, SqlDataReader, T>)dm.CreateDelegate(typeof(Func <ValueFromDBConverter, SqlDataReader, T>)));
        }
Exemplo n.º 2
0
 public SnappyEngine(string connectionString, ValueFromDBConverter valueFromDBConverter = null, ValueToDBConverter valueToDBConverter = null)
 {
     this.valueFromDBConverter = valueFromDBConverter ?? new ValueFromDBConverter();
     this.valueToDBConverter   = valueToDBConverter ?? new ValueToDBConverter();
     ConnectionFactory         = new SqlConnectionFactory(connectionString);
 }
Exemplo n.º 3
0
 public SnappyEngine(ISqlConnectionFactory connectionFactory, ValueFromDBConverter valueFromDBConverter = null, ValueToDBConverter valueToDBConverter = null)
 {
     this.valueFromDBConverter = valueFromDBConverter ?? new ValueFromDBConverter();
     this.valueToDBConverter   = valueToDBConverter ?? new ValueToDBConverter();
     ConnectionFactory         = connectionFactory;
 }
Exemplo n.º 4
0
 internal ObjectReader(Func <ValueFromDBConverter, SqlDataReader, T> reader,
                       ValueFromDBConverter valueFromDBConverter)
 {
     this.reader = reader;
     this.valueFromDBConverter = valueFromDBConverter;
 }
Exemplo n.º 5
0
        internal static ObjectReader <T> CreateObjectReader <T>(ValueFromDBConverter valueFromDBConverter) where T : class
        {
            var reader = GenReader <T>(valueFromDBConverter);

            return(new ObjectReader <T>(reader, valueFromDBConverter));
        }