コード例 #1
0
        public void NullableParameterInOperatorConvert()
        {
            var(convertFromDecimalLambdaExpression1, convertFromDecimalLambdaExpression2, b1)
                = ConvertBuilder.GetConverter(null, typeof(decimal), typeof(CustomMoneyType));

            var convertFromDecimalFunc1 = (Func <decimal, CustomMoneyType>)convertFromDecimalLambdaExpression1.Compile();
            var convertFromDecimalFunc2 = (Func <decimal, CustomMoneyType>)convertFromDecimalLambdaExpression2.Compile();

            Assert.AreEqual(new CustomMoneyType {
                Amount = 1.11m
            }, convertFromDecimalFunc1(1.11m));
            Assert.AreEqual(new CustomMoneyType {
                Amount = 1.11m
            }, convertFromDecimalFunc2(1.11m));

            var(convertFromNullableDecimalLambdaExpression1, convertFromNullableDecimalLambdaExpression2, b2)
                = ConvertBuilder.GetConverter(null, typeof(decimal?), typeof(CustomMoneyType));

            var convertFromNullableDecimalFunc1 = (Func <decimal?, CustomMoneyType>)convertFromNullableDecimalLambdaExpression1.Compile();
            var convertFromNullableDecimalFunc2 = (Func <decimal?, CustomMoneyType>)convertFromNullableDecimalLambdaExpression2.Compile();

            Assert.AreEqual(new CustomMoneyType {
                Amount = 1.11m
            }, convertFromNullableDecimalFunc1(1.11m));
            Assert.AreEqual(new CustomMoneyType {
                Amount = 1.11m
            }, convertFromNullableDecimalFunc2(1.11m));

            Assert.AreEqual(new CustomMoneyType {
                Amount = null
            }, convertFromNullableDecimalFunc1(null));
            Assert.AreEqual(new CustomMoneyType {
                Amount = null
            }, convertFromNullableDecimalFunc2(null));
        }
コード例 #2
0
        public void ConvertNullableEnum()
        {
            var schema = new MappingSchema("2");

            Assert.That(schema.GetDefaultValue(typeof(Enum1?)), Is.Null);
            var mapType = ConvertBuilder.GetDefaultMappingFromEnumType(schema, typeof(Enum1?));

            Assert.That(mapType, Is.EqualTo(typeof(int?)));
            var convertedValue = Converter.ChangeType(null, mapType, schema);

            Assert.IsNull(convertedValue);
        }
コード例 #3
0
ファイル: MappingSchema.cs プロジェクト: 2594636985/Miracle
        public object EnumToValue(Enum value)
        {
            var toType = ConvertBuilder.GetDefaultMappingFromEnumType(this, value.GetType());

            return(Converter.ChangeType(value, toType, this));
        }
コード例 #4
0
        static Expression GetColumnReader(
            IDataContext dataContext, MappingSchema mappingSchema, IDataReader dataReader, Type type, int idx, Expression dataReaderExpr)
        {
            var toType = type.ToNullableUnderlying();

            var ex = dataContext.GetReaderExpression(mappingSchema, dataReader, idx, dataReaderExpr, toType);

            if (ex.NodeType == ExpressionType.Lambda)
            {
                var l = (LambdaExpression)ex;

                switch (l.Parameters.Count)
                {
                case 1: ex = l.GetBody(dataReaderExpr);                break;

                case 2: ex = l.GetBody(dataReaderExpr, Constant(idx)); break;
                }
            }

            if (toType.IsEnumEx())
            {
                var mapType = ConvertBuilder.GetDefaultMappingFromEnumType(mappingSchema, toType);

                if (mapType != ex.Type)
                {
                    // Use only defined convert
                    var econv = mappingSchema.GetConvertExpression(ex.Type, type, false, false) ??
                                mappingSchema.GetConvertExpression(ex.Type, mapType, false);

                    if (econv.Body.GetCount(e => e == econv.Parameters[0]) > 1)
                    {
                        var variable = Variable(ex.Type);
                        var assign   = Assign(variable, ex);

                        ex = Block(new[] { variable }, new[] { assign, econv.GetBody(variable) });
                    }
                    else
                    {
                        ex = econv.GetBody(ex);
                    }
                }
            }

            var conv = mappingSchema.GetConvertExpression(ex.Type, type, false);

            // Replace multiple parameters with single variable or single parameter with the reader expression.
            //
            if (conv.Body.GetCount(e => e == conv.Parameters[0]) > 1)
            {
                var variable = Variable(ex.Type);
                var assign   = Assign(variable, ex);

                ex = Block(new[] { variable }, new[] { assign, conv.GetBody(variable) });
            }
            else
            {
                ex = conv.GetBody(ex);
            }

            // Add check null expression.
            // Note: Oracle may return wrong IsDBNullAllowed, so added additional check toType != type, that means nullable type
            //
            if (toType != type || (dataContext.IsDBNullAllowed(dataReader, idx) ?? true))
            {
                ex = Condition(
                    Call(dataReaderExpr, _isDBNullInfo, Constant(idx)),
                    Constant(mappingSchema.GetDefaultValue(type), type),
                    ex);
            }

            return(ex);
        }
コード例 #5
0
        private static DataParameter[] GetDataParameters(DataConnection dataConnection, object parameters)
        {
            if (parameters == null)
            {
                return(null);
            }

            var dataParameters = parameters as DataParameter[];

            if (dataParameters != null)
            {
                return(dataParameters);
            }

            var parameter = parameters as DataParameter;

            if (parameter != null)
            {
                return new[] { parameter }
            }
            ;

            Func <object, DataParameter[]> func;
            var type = parameters.GetType();
            var key  = new ParamKey(type, dataConnection.ID);

            if (!_parameterReaders.TryGetValue(key, out func))
            {
                var td = dataConnection.MappingSchema.GetEntityDescriptor(type);

                var p   = Expression.Parameter(typeof(object), "p");
                var obj = Expression.Parameter(parameters.GetType(), "obj");

                var expr = Expression.Lambda <Func <object, DataParameter[]> >(
                    Expression.Block(
                        new[] { obj }, Expression.Assign(obj, Expression.Convert(p, type)), Expression.NewArrayInit(
                            typeof(DataParameter),
                            td.Columns.Select(m =>
                {
                    if (m.MemberType == typeof(DataParameter))
                    {
                        var pobj = Expression.Parameter(typeof(DataParameter));

                        return(Expression.Block(
                                   new[] { pobj },
                                   Expression.Assign(pobj, Expression.PropertyOrField(obj, m.MemberName)),
                                   Expression.MemberInit(
                                       Expression.New(typeof(DataParameter)),
                                       Expression.Bind(
                                           _dataParameterName,
                                           Expression.Coalesce(
                                               Expression.MakeMemberAccess(pobj, _dataParameterName),
                                               Expression.Constant(m.ColumnName))),
                                       Expression.Bind(
                                           _dataParameterDataType,
                                           Expression.MakeMemberAccess(pobj, _dataParameterDataType)),
                                       Expression.Bind(
                                           _dataParameterValue,
                                           Expression.Convert(
                                               Expression.MakeMemberAccess(pobj, _dataParameterValue),
                                               typeof(object))))));
                    }

                    var memberType  = m.MemberType.ToNullableUnderlying();
                    var valueGetter = Expression.PropertyOrField(obj, m.MemberName) as Expression;
                    var mapper      = dataConnection.MappingSchema.GetConvertExpression(memberType,
                                                                                        typeof(DataParameter), createDefault: false);

                    if (mapper != null)
                    {
                        return(Expression.Call(
                                   MemberHelper.MethodOf(() => PrepareDataParameter(null, null)),
                                   mapper.GetBody(valueGetter),
                                   Expression.Constant(m.ColumnName)));
                    }

                    if (memberType.IsEnum)
                    {
                        var mapType =
                            ConvertBuilder.GetDefaultMappingFromEnumType(dataConnection.MappingSchema,
                                                                         memberType);
                        var convExpr = dataConnection.MappingSchema.GetConvertExpression(m.MemberType,
                                                                                         mapType);

                        memberType  = mapType;
                        valueGetter = convExpr.GetBody(valueGetter);
                    }

                    return((Expression)Expression.MemberInit(
                               Expression.New(typeof(DataParameter)),
                               Expression.Bind(
                                   _dataParameterName,
                                   Expression.Constant(m.ColumnName)),
                               Expression.Bind(
                                   _dataParameterDataType,
                                   Expression.Constant(
                                       dataConnection.MappingSchema.GetDataType(memberType).DataType)),
                               Expression.Bind(
                                   _dataParameterValue,
                                   Expression.Convert(valueGetter, typeof(object)))));
                }))),
                    p);

                _parameterReaders[key] = func = expr.Compile();
            }

            return(func(parameters));
        }
コード例 #6
0
        static Expression GetColumnReader(
            IDataContext dataContext, MappingSchema mappingSchema, IDataReader dataReader, Type type, IValueConverter?converter, int idx, Expression dataReaderExpr, bool forceNullCheck)
        {
            var toType = type.ToNullableUnderlying();

            Expression ex;

            if (converter != null)
            {
                var expectedProvType = converter.FromProviderExpression.Parameters[0].Type;
                ex = dataContext.GetReaderExpression(dataReader, idx, dataReaderExpr, expectedProvType);
            }
            else
            {
                ex = dataContext.GetReaderExpression(dataReader, idx, dataReaderExpr, toType);
            }

            if (ex.NodeType == ExpressionType.Lambda)
            {
                var l = (LambdaExpression)ex;

                switch (l.Parameters.Count)
                {
                case 1: ex = l.GetBody(dataReaderExpr);                                 break;

                case 2: ex = l.GetBody(dataReaderExpr, ExpressionInstances.Int32(idx)); break;
                }
            }

            if (converter != null)
            {
                // we have to prepare read expression to conversion
                //
                var expectedType = converter.FromProviderExpression.Parameters[0].Type;

                if (converter.HandlesNulls)
                {
                    ex = Condition(
                        Call(dataReaderExpr, Methods.ADONet.IsDBNull, ExpressionInstances.Int32Array(idx)),
                        Constant(mappingSchema.GetDefaultValue(expectedType), expectedType),
                        ex);
                }

                if (expectedType != ex.Type)
                {
                    ex = ConvertExpressionToType(ex, expectedType, mappingSchema);
                }

                ex = InternalExtensions.ApplyLambdaToExpression(converter.FromProviderExpression, ex);
                if (toType != ex.Type && toType.IsAssignableFrom(ex.Type))
                {
                    ex = Convert(ex, toType);
                }
            }
            else if (toType.IsEnum)
            {
                var mapType = ConvertBuilder.GetDefaultMappingFromEnumType(mappingSchema, toType) !;

                if (mapType != ex.Type)
                {
                    // Use only defined convert
                    var econv = mappingSchema.GetConvertExpression(ex.Type, type, false, false) ??
                                mappingSchema.GetConvertExpression(ex.Type, mapType, false) !;

                    ex = InternalExtensions.ApplyLambdaToExpression(econv, ex);
                }
            }

            if (ex.Type != type)
            {
                ex = ConvertExpressionToType(ex, type, mappingSchema) !;
            }

            // Try to search postprocessing converter TType -> TType
            //
            ex = ConvertExpressionToType(ex, ex.Type, mappingSchema) !;

            // Add check null expression.
            // If converter handles nulls, do not provide IsNull check
            // Note: some providers may return wrong IsDBNullAllowed, so we enforce null check in slow mode. E.g.:
            // Microsoft.Data.SQLite
            // Oracle (group by columns)
            // MySql.Data and some other providers enforce null check in IsDBNullAllowed implementation
            if (converter?.HandlesNulls != true &&
                (forceNullCheck || (dataContext.IsDBNullAllowed(dataReader, idx) ?? true)))
            {
                ex = Condition(
                    Call(dataReaderExpr, Methods.ADONet.IsDBNull, ExpressionInstances.Int32Array(idx)),
                    Constant(mappingSchema.GetDefaultValue(type), type),
                    ex);
            }

            return(ex);
        }