private static Type Create(DataReaderCache cache) { TypeBuilder tb = _mb.DefineType( $"DynamicType_#{cache.GetColumnHash()}", TypeAttributes.Public); for (int fieldIndex = 0; fieldIndex < cache.Reader.FieldCount; fieldIndex++) { tb.DefineField( cache.Reader.GetName(fieldIndex), cache.Reader.GetFieldType(fieldIndex), FieldAttributes.Public); } return(tb.CreateTypeInfo()); }
public static Type Get(DataReaderCache cache) { if (cache == null) { throw new ArgumentNullException(nameof(cache)); } if (!_cache.TryGetValue(cache.GetColumnHash(), out Type value)) { lock (_lock) { if (!_cache.TryGetValue(cache.GetColumnHash(), out value)) { value = Create(cache); _cache.Add(cache.GetColumnHash(), value); } } } return(value); }
public static Func <IDataRecord, object> CreateMap(DataReaderCache cache) { if (cache == null) { throw new ArgumentNullException(nameof(cache)); } if (!_maps.TryGetValue(cache.GetColumnHash(), out Func <IDataRecord, object> func)) { lock (_lock) { if (!_maps.TryGetValue(cache.GetColumnHash(), out func)) { func = Create(cache); _maps.Add(cache.GetColumnHash(), func); } } } return(func); }
public static Func <IDataRecord, T> Create(DataReaderCache cache) { if (cache == null) { throw new ArgumentNullException(nameof(cache)); } if (!_cache.TryGetValue(cache.GetColumnHash(), out Func <IDataRecord, T> func)) { lock (_lock) { if (!_cache.TryGetValue(cache.GetColumnHash(), out func)) { func = CreateHelper(cache.Reader); _cache.Add(cache.GetColumnHash(), func); } } } return(func); }
private static Func <IDataRecord, object> Create(DataReaderCache cache) { Type instanceType = DynamicType.Get(cache); var instance = Expression.Variable(instanceType, "instance"); var value = Expression.Variable(typeof(object), "value"); var record = Expression.Parameter(typeof(IDataRecord), "record"); var expressions = new List <Expression> { Expression.Assign(instance, Expression.New(instanceType)) }; for (var fieldIndex = 0; fieldIndex < cache.Reader.FieldCount; fieldIndex++) { var fieldName = cache.Reader.GetName(fieldIndex); var fieldType = cache.Reader.GetFieldType(fieldIndex); var getValueCall = Expression.Call( record, _getValueMethod, Expression.Constant(fieldIndex)); var isNotDbNull = Expression.NotEqual( value, Expression.Constant(DBNull.Value, typeof(object))); var memberExpression = Expression.MakeMemberAccess( instance, instanceType.GetField(fieldName)); var setCall = Expression.Assign( memberExpression, Expression.Convert(value, fieldType)); // Get the Value expressions.Add(Expression.Assign( value, getValueCall)); // Only bother setting the value if is not dbnull, // otherwise let the field stay at the default value expressions.Add(Expression.IfThen( isNotDbNull, setCall)); } var labelTarget = Expression.Label(typeof(object)); var labelExpression = Expression.Label(labelTarget, Expression.Default(typeof(object))); expressions.Add(Expression.Return( labelTarget, Expression.Convert(instance, typeof(object)))); expressions.Add(labelExpression); BlockExpression block = Expression.Block( new[] { instance, value }, expressions); var lambda = Expression.Lambda <Func <IDataRecord, object> >( block, record); return(lambda.Compile()); }