private static MethodCallExpression SetValue(ParameterExpression result, Type fromType, Column to, Expression value)
        {
            if (to.Type != fromType)
            {
                // type if not the same, can it be assigned?
                if (Types.CanBeCast(fromType, to.Type))
                {
                    value = Expression.Convert(value, to.Type);
                }
                else if (Types.IsNullable(fromType) && fromType.GetGenericArguments()[0] == to.Type)
                {
                    value = Expression.Convert(value, to.Type);
                }
                else if (Types.IsNullable(fromType) && Types.CanBeCast(fromType.GetGenericArguments()[0], to.Type))
                {
                    value = Expression.Convert(value, to.Type);
                }
                else
                {
                    return(null);
                }
            }

            if (to.Type == typeof(byte[]))
            {
                var setBytes = typeof(SqlDataRecord).GetMethod("SetBytes", new[] { typeof(int), typeof(long), typeof(byte[]), typeof(int), typeof(int) });
                Contract.Assert(setBytes != null);
                return(Expression.Call(result, setBytes, Expression.Constant(to.Ordinal), Expression.Constant(0L), value, Expression.Constant(0), Expression.PropertyOrField(value, "Length")));
            }

            var setMethod = typeof(SqlDataRecord).GetMethod(SetMethodName(to.Type), new[] { typeof(int), to.Type });

            Contract.Assert(setMethod != null);
            return(Expression.Call(result, setMethod, Expression.Constant(to.Ordinal), value));
        }
Example #2
0
        static Expression ReadValue(ParameterExpression input, Mapping <Thing, Thing> map)
        {
            Expression value    = Expression.PropertyOrField(input, map.From.Name);
            var        fromType = map.From.Type;
            var        toType   = map.To.Type;

            if (fromType == toType)
            {
                return(value);
            }
            if (Types.CanBeCast(fromType, toType)) // e.g. int to long
            {
                return(Expression.Convert(value, toType));
            }
            if (Types.IsNullable(fromType))
            {
                Expression fromValueOrDefault = Expression.Call(value, fromType.GetMethod("GetValueOrDefault", Type.EmptyTypes));
                var        fromArgType        = Types.NullableOf(fromType);
                if (fromArgType == toType) // e.g. int? to int
                {
                    return(fromValueOrDefault);
                }
                var cast = Types.GetExplicitCastOperator(fromArgType, toType);
                if (cast != null) // e.g. IntId<>? to int
                {
                    return(Expression.Call(cast, fromValueOrDefault));
                }
                if (Types.IsNullable(toType))
                {
                    // nullable<> to nullable<> conversion must handle null to null as a special case

                    var toArgType = toType.GetGenericArguments()[0];
                    if (Types.CanBeCast(fromArgType, toType)) // e.g. int? to long?
                    {
                        return(Expression.Condition(Expression.PropertyOrField(value, "HasValue"), Expression.Convert(fromValueOrDefault, toType), Expression.Default(toType)));
                    }

                    cast = Types.GetExplicitCastOperator(fromArgType, toArgType);  // e.g. IntId<>? to int?
                    if (cast != null)
                    {
                        fromValueOrDefault = Expression.Call(cast, fromValueOrDefault);
                    }

                    return(Expression.Condition(Expression.PropertyOrField(value, "HasValue"), Expression.Convert(fromValueOrDefault, toType), Expression.Default(toType)));
                }
                if (Types.CanBeCast(fromArgType, toType)) // e.g. int? to long
                {
                    return(Expression.Convert(fromValueOrDefault, toType));
                }
            }
            if (Types.IsNullable(toType))
            {
                var toArgType = toType.GetGenericArguments()[0];
                var cast2     = Types.GetExplicitCastOperator(fromType, toArgType); // e.g. IntId<> to int?
                if (cast2 != null)
                {
                    return(Expression.Convert(Expression.Call(cast2, value), toType));
                }
            }
            var cast3 = Types.GetExplicitCastOperator(fromType, toType); // e.g. IntId<> to int

            if (cast3 != null)
            {
                return(Expression.Call(cast3, value));
            }
            throw new InvalidOperationException("Should never get here has types compatibility has been checked");
        }