private ConstructedValueExpression CompileArrayOfScalar(MapTypeContext context, ConstructorInfo constructor, List <ColumnInfo> columns, Type elementType) { var arrayVar = context.CreateVariable(context.TargetType, "array"); var expressions = new List <Expression>(); var variables = new List <ParameterExpression>(); variables.Add(arrayVar); expressions.Add( Expression.Assign( arrayVar, Expression.New( constructor, Expression.Constant(columns.Count) ) ) ); for (int i = 0; i < columns.Count; i++) { var columnState = context.GetSubstateForColumn(columns[i], elementType, null); var getScalarExpression = _scalars.Compile(columnState); expressions.AddRange(getScalarExpression.Expressions); expressions.Add( Expression.Assign( Expression.ArrayAccess( arrayVar, Expression.Constant(i) ), getScalarExpression.FinalValue ) ); variables.AddRange(getScalarExpression.Variables); } return(new ConstructedValueExpression(expressions, arrayVar, variables)); }
public static ConstructedValueExpression GetCollectionPopulateStatements(ICompiler scalars, ICompiler nonScalars, MapTypeContext context, Type elementType, Expression listVar, MethodInfo addMethod) { if (!context.HasColumns()) { return(new ConstructedValueExpression(null)); } var expressions = new List <Expression>(); var variables = new List <ParameterExpression>(); // For scalar types (object is treated like a scalar here), map each column to an entry in the // array, consuming all remaining columns. if (elementType.IsSupportedPrimitiveType() || elementType == typeof(object)) { var columns = context.GetColumns(); foreach (var column in columns) { var columnState = context.GetSubstateForColumn(column, elementType, null); var result = scalars.Compile(columnState); expressions.AddRange(result.Expressions); expressions.Add( Expression.Call( listVar, addMethod, result.FinalValue ) ); variables.AddRange(result.Variables); } return(new ConstructedValueExpression(expressions, null, variables)); } // For all non-scalar types // loop so long as we have columns and consume columns every iteration. var elementState = context.ChangeTargetType(elementType); var numberOfColumns = context.NumberOfColumns(); while (numberOfColumns > 0) { var result = nonScalars.Compile(elementState); var newNumberOfColumns = context.NumberOfColumns(); // We haven't consumed any new columns, so we're done. if (newNumberOfColumns == numberOfColumns) { break; } expressions.AddRange(result.Expressions); expressions.Add( Expression.Call(listVar, addMethod, result.FinalValue) ); variables.AddRange(result.Variables); numberOfColumns = newNumberOfColumns; } return(new ConstructedValueExpression(expressions, null, variables)); }
public static ConstructedValueExpression AddDictionaryPopulateStatements(ICompiler values, MapTypeContext context, Type elementType, Expression dictVar, MethodInfo addMethod) { var expressions = new List <Expression>(); var variables = new List <ParameterExpression>(); if (context.Name == null) { var firstColumnsByName = context.GetFirstIndexForEachColumnName(); foreach (var column in firstColumnsByName) { var substate = context.GetSubstateForProperty(column.CanonicalName, null, elementType); var getScalarExpression = values.Compile(substate); expressions.AddRange(getScalarExpression.Expressions); expressions.Add( Expression.Call( dictVar, addMethod, Expression.Constant(column.OriginalName), getScalarExpression.FinalValue ) ); variables.AddRange(getScalarExpression.Variables); } return(new ConstructedValueExpression(expressions, null, variables)); } var columns = context.GetFirstIndexForEachColumnName(); foreach (var column in columns) { var keyName = column.OriginalName.Substring(context.CurrentPrefix.Length); var childName = column.CanonicalName.Substring(context.CurrentPrefix.Length); var columnSubstate = context.GetSubstateForColumn(column, elementType, childName); var getScalarExpression = values.Compile(columnSubstate); expressions.AddRange(getScalarExpression.Expressions); expressions.Add( Expression.Call( dictVar, addMethod, Expression.Constant(keyName), getScalarExpression.FinalValue ) ); variables.AddRange(getScalarExpression.Variables); } return(new ConstructedValueExpression(expressions, null, variables)); }
public ConstructedValueExpression Compile(MapTypeContext context) { if (context.TargetType != typeof(object)) { return(ConstructedValueExpression.Nothing); } // At the top-level (name==null) we convert to dictionary to preserve column name information if (context.Name == null) { // Dictionary mapping logic will group by key name and recurse. When we get back to the // ObjectCompiler, we will have a smaller set of columns and we will have a non-null name var dictState = context.ChangeTargetType(typeof(Dictionary <string, object>)); var dictExpr = _dictionaries.Compile(dictState); return(new ConstructedValueExpression(dictExpr.Expressions, Expression.Convert(dictExpr.FinalValue, typeof(object)), dictExpr.Variables)); } var columns = context.GetColumns().ToList(); var numColumns = columns.Count; // If we have no columns, just return null if (numColumns == 0) { return(new ConstructedValueExpression( Expression.Convert( Expression.Constant(null), typeof(object) ) )); } // If we have exactly one column, map the value as a scalar and return a single result if (numColumns == 1) { var firstColumn = columns[0]; var objectState = context.GetSubstateForColumn(firstColumn, typeof(object), null); var asScalar = _scalars.Compile(objectState); return(new ConstructedValueExpression(asScalar.Expressions, Expression.Convert(asScalar.FinalValue, typeof(object)), asScalar.Variables)); } // If we have more than one column, map to object[] var arrayState = context.ChangeTargetType(typeof(object[])); var exprs = _arrays.Compile(arrayState); return(new ConstructedValueExpression(exprs.Expressions, Expression.Convert(exprs.FinalValue, typeof(object)), exprs.Variables)); }