public static DataMapper GetMapper(IDbCommand command, IDataReader reader) { var cacheKey = new DataMapperCache.Key(command, typeof(BlazerDynamicObject)); if (DataMapperCache.TryGet(cacheKey, out DataMapper cachedMapper)) { return(cachedMapper); } var columns = new string[reader.FieldCount]; for (int i = 0; i < reader.FieldCount; i++) { columns[i] = reader.GetName(i); } DataMapper lambda = (record) => { var values = new object[record.FieldCount]; var blzDynamic = new BlazerDynamicObject(values.Length); record.GetValues(values); for (int i = 0; i < values.Length; i++) { var value = values[i]; blzDynamic.Set(columns[i], value == DBNull.Value ? null : value); } return(blzDynamic); }; DataMapperCache.Add(cacheKey, lambda); return(lambda); }
public static DataMapper GetMapper <T>(IDbCommand command, IDataReader reader) where T : new() { var entityType = typeof(T); var cacheKey = new DataMapperCache.Key(command, entityType); if (DataMapperCache.TryGet(cacheKey, out DataMapper cachedMapper)) { return(cachedMapper); } var dataRecordType = typeof(IDataRecord); var dataRecordParamExpr = Expression.Parameter(dataRecordType, "record"); var dataRecordIsDbNullMethod = dataRecordType.GetMethod(nameof(IDataRecord.IsDBNull), new[] { typeof(int) }); var mapperBodyExpressions = new List <Expression>(); var returnLabelExpr = Expression.Label(entityType); // T entity; var entityVarExpr = Expression.Variable(entityType, "entity"); // entity = new T(); var entityNewExpr = Expression.Assign( entityVarExpr, Expression.New(entityType)); mapperBodyExpressions.Add(entityNewExpr); for (int i = 0; i < reader.FieldCount; i++) { var entityField = GetEntityField(entityType, reader.GetName(i)); if (entityField == null) { continue; } Type entityFieldType = null; Expression entityFieldExpr = null; if (entityField is PropertyInfo propInfo) { entityFieldType = propInfo.PropertyType; entityFieldExpr = Expression.Property(entityVarExpr, propInfo); } else if (entityField is FieldInfo fieldInfo) { entityFieldType = fieldInfo.FieldType; entityFieldExpr = Expression.Field(entityVarExpr, fieldInfo); } var ctx = new Context() { EntityFieldType = entityFieldType, EntityFieldExpr = entityFieldExpr, DataRecordParameterExpr = dataRecordParamExpr, DataRecordIsDbNullMethod = dataRecordIsDbNullMethod, FieldIndex = i }; mapperBodyExpressions.Add(GetFieldMapperExpression(ctx)); } // return entity; var entityReturnExpr = Expression.Return(returnLabelExpr, entityVarExpr); mapperBodyExpressions.Add(entityReturnExpr); // default return value var defaultReturnExpr = Expression.Label(returnLabelExpr, Expression.Constant(null, entityType)); mapperBodyExpressions.Add(defaultReturnExpr); var lambdaBodyExpr = Expression.Block( new[] { entityVarExpr }, mapperBodyExpressions); var lambdaExpr = Expression.Lambda <DataMapper>(lambdaBodyExpr, dataRecordParamExpr); var lambda = lambdaExpr.Compile(); DataMapperCache.Add(cacheKey, lambda); return(lambda); }