Esempio n. 1
0
        public T Fill <T>()
        {
            var t    = PrimitiveTypeFiller.GetFillMethod <T>();
            var type = typeof(T);

            if (type.IsPrimitive || PrimitiveTypeFiller.TypesToTreatAsPrimitives.Contains(type))
            {
                return(PrimitiveTypeFiller.GetReaderValue <T>(reader, index: 0));
            }
            else if (type.IsNullable() &&
                     !IdTypeExtension.IsNullableIdType <T>() &&
                     !LongIdTypeExtension.IsNullableLongIdType <T>())
            {
                if (reader.IsDBNull(0))
                {
                    return(default(T));
                }

                return(PrimitiveTypeFiller.GetReaderValue <T>(reader, index: 0));
            }
            else if (type == typeof(object))
            {
                return((T)reader.GetValue(0));
            }
            else
            {
                var filler = objectFillerFactory.GetObjectFiller();
                T   entity = (T)filler.Build(type, reader);
                return(entity);
            }
        }
Esempio n. 2
0
        public QueryEl In(IEnumerable <T> values)
        {
            var valuesList = values as ICollection <T>;

            if (valuesList == null && values != null)
            {
                valuesList = values.ToList();
            }

            if (valuesList == null ||
                valuesList.Count == 0)
            {
                // Always false
                return(new QueryElBool(false));
            }

            if (valuesList.Count == 1)
            {
                // If the SQL-Server knows there is only a single value, it does a much better job at optimizing the query
                // Do not generate an In-Statement in this case.
                return(new QueryElOperator <T>("({0}={1})", this, QueryConversionHelper.ConvertParameter(valuesList.Single())));
            }

            if (IdTypeExtension.IsIdType <T>() || IdTypeExtension.IsNullableIdType <T>())
            {
                var intsList = valuesList
                               .Where(v => v != null)
                               .Select(v => ((IConvertibleToInt32)v).ConvertToInt32())
                               // 2TK BDA initCapacity: valuesList.Count
                               .ToList();
                return(new QueryElSetOperator <int>("({0} IN (SELECT Value FROM {1}))", this, intsList));
            }

            if (LongIdTypeExtension.IsLongIdType <T>() || LongIdTypeExtension.IsNullableLongIdType <T>())
            {
                var longsList = valuesList
                                .Where(v => v != null)
                                .Select(v => ((IConvertibleToInt64)v).ConvertToInt64())
                                // 2TK BDA initCapacity: valuesList.Count
                                .ToList();
                return(new QueryElSetOperator <long>("({0} IN (SELECT Value FROM {1}))", this, longsList));
            }

            if (typeof(T) == typeof(string) || typeof(T) == typeof(int) || typeof(T) == typeof(int?))
            {
                return(new QueryElSetOperator <T>("({0} IN (SELECT Value FROM {1}))", this, valuesList));
            }

            var vals = valuesList.JoinString(",", onlyNonEmptyValues: true);

            if (string.IsNullOrEmpty(vals))
            {
                return(new QueryElBool(false));
            }

            return(new QueryElFormat("({0} IN ({1}))", this, vals));
        }
Esempio n. 3
0
 private static bool IsTypeMismatch(Type fieldType, Type unboxedType)
 {
     return((unboxedType != fieldType) &&
            !(unboxedType.IsEnum && Enum.GetUnderlyingType(unboxedType) == fieldType) &&
            !(unboxedType == typeof(char) && fieldType == typeof(string)) &&
            !(unboxedType.IsEnum && fieldType == typeof(string)) &&
            !(IdTypeExtension.IsIdType(unboxedType) && (fieldType == typeof(int))) &&
            !(IdTypeExtension.IsNullableIdType(unboxedType) && (fieldType == typeof(int?))) &&
            !(LongIdTypeExtension.IsLongIdType(unboxedType) && fieldType == typeof(long)) &&
            !(LongIdTypeExtension.IsNullableLongIdType(unboxedType) && fieldType == typeof(long?)));
 }
Esempio n. 4
0
        private static void AddNonNullableNeighbor(
            DbEntity entity,
            DbEntity neighbor,
            PropertyInfo pi,
            PropertyInfo pointerToEntity,
            IList <Tuple <PropertyInfo, DbEntity> > propertyInfos)
        {
            if (pointerToEntity.PropertyType == typeof(int))
            {
                int pointerValueToEntity = (int)pointerToEntity.GetValue(neighbor, null);
                if (pointerValueToEntity == ((IId)entity).Id)
                {
                    propertyInfos.Add(new Tuple <PropertyInfo, DbEntity>(pi, neighbor));
                }
            }
            else if (pointerToEntity.PropertyType == typeof(long))
            {
                long pointerValueToEntity = (long)pointerToEntity.GetValue(neighbor, null);
                if (pointerValueToEntity == ((ILongId)entity).Id)
                {
                    propertyInfos.Add(new Tuple <PropertyInfo, DbEntity>(pi, neighbor));
                }
            }
            else if (IdTypeExtension.IsIdType(pointerToEntity.PropertyType))
            {
                var rowId = (int)pointerToEntity.GetValue(neighbor, null).Convert(typeof(int));

                if (rowId == ((IId)entity).Id)
                {
                    propertyInfos.Add(new Tuple <PropertyInfo, DbEntity>(pi, neighbor));
                }
            }
            else if (LongIdTypeExtension.IsLongIdType(pointerToEntity.PropertyType))
            {
                var rowId = (long)pointerToEntity.GetValue(neighbor, null).Convert(typeof(long));

                if (rowId == ((ILongId)entity).Id)
                {
                    propertyInfos.Add(new Tuple <PropertyInfo, DbEntity>(pi, neighbor));
                }
            }
        }
Esempio n. 5
0
        public T SelectSingleValue <T>()
        {
            if (SqlCommand.Connection == null)
            {
                throw new InvalidOperationException("SqlCommand.Connection is not set.");
            }

            using (QueryTime.Measure(this))
            {
                var value = sqlCommand.ExecuteScalar();
                if (value == null)
                {
                    return(default(T));
                }

                // Special case for Id<> and LongId<>
                var targetConvertType = typeof(T);
                if (IdTypeExtension.IsIdType(targetConvertType))
                {
                    var constructor = targetConvertType.GetConstructor(new[] { typeof(int) });
                    if (constructor == null)
                    {
                        throw new InvalidCastException("The Id<> type has no constructor taking int as a parameter.");
                    }

                    return((T)constructor.Invoke(new object[] { Convert.ToInt32(value) }));
                }
                else if (LongIdTypeExtension.IsLongIdType(targetConvertType))
                {
                    var constructor = targetConvertType.GetConstructor(new[] { typeof(long) });
                    if (constructor == null)
                    {
                        throw new InvalidCastException("The LongId<> type has no constructor taking long as a parameter.");
                    }

                    return((T)constructor.Invoke(new object[] { Convert.ToInt64(value) }));
                }

                // Just execute the query, don't close the connection
                return(DataRowExtensionsCustom.Get <T>(value));
            }
        }
Esempio n. 6
0
        private Delegate GetObjectFillerDelegate(Type type, IDataRecord reader)
        {
            var fieldCount         = reader.FieldCount;
            var fieldNames         = new string[fieldCount];
            var fieldTypes         = new Type[fieldCount];
            var fieldDataTypeNames = new string[fieldCount];

            for (var i = 0; i < fieldCount; i++)
            {
                fieldNames[i]         = reader.GetName(i);
                fieldTypes[i]         = reader.GetFieldType(i);
                fieldDataTypeNames[i] = reader.GetDataTypeName(i);
            }

            var typeConstructor = FindConstructor(type, fieldNames, fieldTypes, fieldDataTypeNames);

            if (typeConstructor == null)
            {
                throw new NullReferenceException($"Could not find a type constructor for {type.Name}");
            }

            var getValueMethod        = typeof(IDataRecord).GetMethod("GetValue");
            var constructorParameters = typeConstructor.GetParameters();

            if (constructorParameters.Length == 0)
            {
                return(GetParameterlessObjectFillerDelegate(type, reader));
            }

            var argument            = Expression.Parameter(typeof(IDataRecord), "source");
            var argumentsExpression = new Expression[constructorParameters.Length];

            for (var i = 0; i < constructorParameters.Length; i++)
            {
                var        indexExpression = Expression.Constant(i);
                Expression loadExpression;
                var        parameterType = constructorParameters[i].ParameterType;
                if (parameterType == typeof(SqlXml))
                {
                    // this may crash as it is SQL specific if IDataRecord is not a SqlDataRecord, we'll leave it here for the time being though to be able to unit test this method against IDataRecord...
                    loadExpression = Expression.Call(argument, DynamicLoadHelpers.GetSqlXmlMethod, indexExpression);
                }
                else if (parameterType == typeof(decimal))
                {
                    loadExpression = Expression.Call(DynamicLoadHelpers.GetDecimalMethodInfo, argument, indexExpression);
                }
                else if (parameterType == typeof(decimal?))
                {
                    loadExpression = Expression.Call(DynamicLoadHelpers.GetNullableDecimalMethodInfo, argument, indexExpression);
                }
                else if (parameterType == typeof(XElement))
                {
                    loadExpression = Expression.Call(argument, getValueMethod, indexExpression);
                    loadExpression = Expression.Call(DynamicLoadHelpers.LoadXElement, loadExpression);
                }
                else if (parameterType == typeof(Binary))
                {
                    loadExpression = Expression.Call(DynamicLoadHelpers.GetBinaryMethodInfo, argument, indexExpression);
                }
                else if (parameterType == typeof(char))
                {
                    loadExpression = Expression.Call(DynamicLoadHelpers.GetCharMathodInfo, argument, indexExpression);
                }
                else if (parameterType == typeof(char?))
                {
                    loadExpression = Expression.Call(DynamicLoadHelpers.GetNullableCharMethodInfo, argument, indexExpression);
                }
                else if (parameterType == typeof(Date))
                {
                    loadExpression = Expression.Call(DynamicLoadHelpers.GetDateMethodInfo, argument, indexExpression);
                }
                else if (parameterType == typeof(Date?))
                {
                    loadExpression = Expression.Call(DynamicLoadHelpers.GetNullableDateMethodInfo, argument, indexExpression);
                }
                else if (IdTypeExtension.IsIdType(parameterType))
                {
                    if (IdTypeExtension.IsNullableIdType(type)) // parameter comes from unboxing of nullable Id struct
                    {
                        var methodInfo = type.GetGenericArguments()[0].GetMethod("Nullable", new[] { typeof(int) });
                        loadExpression = Expression.Call(null, methodInfo,
                                                         Expression.Call(null, DynamicLoadHelpers.GetNullableIntMethodInfo, argument, Expression.Constant(i)));
                        var nullableIdLambda = Expression.Lambda(loadExpression, argument);
                        return(nullableIdLambda.Compile());
                    }
                    else
                    {
                        loadExpression = Expression.Call(DynamicLoadHelpers.GetIdParameterMethodInfo, argument, indexExpression);
                        var constructor = parameterType.GetConstructor(new[] { typeof(int) });
                        loadExpression = Expression.New(constructor, loadExpression);
                    }
                }
                else if (IdTypeExtension.IsNullableIdType(parameterType))
                {
                    var methodInfo = parameterType.GetGenericArguments()[0].GetMethod("Nullable", new[] { typeof(int) });
                    loadExpression = Expression.Call(null, methodInfo,
                                                     Expression.Call(null, DynamicLoadHelpers.GetNullableIntMethodInfo, argument, Expression.Constant(i)));
                }
                else if (LongIdTypeExtension.IsLongIdType(parameterType))
                {
                    if (LongIdTypeExtension.IsNullableLongIdType(type)) // parameter comes from unboxing of nullable Id struct
                    {
                        var methodInfo = type.GetGenericArguments()[0].GetMethod("Nullable", new[] { typeof(long) });
                        loadExpression = Expression.Call(null, methodInfo,
                                                         Expression.Call(null, DynamicLoadHelpers.GetNullableLongMethodInfo, argument, Expression.Constant(i)));
                        var nullableIdLambda = Expression.Lambda(loadExpression, argument);
                        return(nullableIdLambda.Compile());
                    }
                    else
                    {
                        loadExpression = Expression.Call(DynamicLoadHelpers.GetLongIdParameterMethodInfo, argument, indexExpression);
                        var constructor = parameterType.GetConstructor(new[] { typeof(long) });
                        loadExpression = Expression.New(constructor, loadExpression);
                    }
                }
                else if (LongIdTypeExtension.IsNullableLongIdType(parameterType))
                {
                    var methodInfo = parameterType.GetGenericArguments()[0].GetMethod("Nullable", new[] { typeof(long) });
                    loadExpression = Expression.Call(null, methodInfo, Expression.Call(null, DynamicLoadHelpers.GetNullableLongMethodInfo, argument, Expression.Constant(i)));
                }
                else
                {
                    var valueExpression        = Expression.Call(argument, getValueMethod, indexExpression);
                    var valueNotNullExpression = Expression.Call(getValueNotDBNullMethod, valueExpression);
                    loadExpression = Expression.Convert(valueNotNullExpression, parameterType);
                }

                argumentsExpression[i] = loadExpression;
            }

            var newExpression = Expression.New(typeConstructor, argumentsExpression);

            var lambda =
                Expression.Lambda(newExpression, argument);

            return(lambda.Compile());
        }
Esempio n. 7
0
        private ConstructorInfo FindConstructor(Type type, string[] fieldNames, Type[] fieldTypes, string[] fieldDataTypeNames)
        {
            var checkFieldNames = true;

            if (type.Name.StartsWith("Tuple`") ||
                IdTypeExtension.IsIdType(type) ||
                IdTypeExtension.IsNullableIdType(type) ||
                LongIdTypeExtension.IsLongIdType(type) ||
                LongIdTypeExtension.IsNullableLongIdType(type) ||
                fieldNames[0].StartsWith("Item"))    // do not check field names when they are all in auto generated as "Item1" "Item2" etc.
            {
                checkFieldNames = false;
            }

            var constructors = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            foreach (var constructor in constructors.OrderBy(c => c.IsPublic ? 0 : (c.IsPrivate ? 2 : 1)).ThenBy(c => c.GetParameters().Length))
            {
                var constructorParameters = constructor.GetParameters();
                if (constructorParameters.Length == 0)
                {
                    return(constructor);
                }

                if (constructorParameters.Length > fieldTypes.Length)
                {
                    continue;
                }

                int i = 0;
                for (; i < constructorParameters.Length; i++)
                {
                    // do not check argument names in case object is a Tuple, else break on name mismatch.
                    if (checkFieldNames &&
                        !String.Equals(constructorParameters[i].Name, fieldNames[i], StringComparison.OrdinalIgnoreCase))
                    {
                        break;
                    }

                    if (fieldTypes[i] == typeof(byte[]) && constructorParameters[i].ParameterType.FullName == "System.Data.Linq.Binary")
                    {
                        continue;
                    }

                    var unboxedType = Nullable.GetUnderlyingType(constructorParameters[i].ParameterType) ?? constructorParameters[i].ParameterType;
                    // SqlDataReader converts the SQL Date type into DateTime by default, that means if we expect a System.Date it would not match
                    if (fieldTypes[i] == typeof(DateTime) &&
                        fieldDataTypeNames[i] == "date" &&
                        unboxedType == typeof(Date))
                    {
                        continue;
                    }

                    if (IsTypeMismatch(fieldTypes[i], unboxedType))
                    {
                        break;
                    }
                }

                if (i == constructorParameters.Length)
                {
                    return(constructor);
                }
            }

            return(null);
        }
Esempio n. 8
0
        private Func <IDataRecord, object> GetParameterlessObjectFillerDelegate(Type type, IDataRecord reader)
        {
            var dest = Expression.Variable(type, "dest");
            var body = new List <Expression>();

            body.Add(Expression.Assign(dest, Expression.New(type)));

            var getValueMethod = typeof(IDataRecord).GetMethod("GetValue");
            var propertyCount  = 0;
            HashSet <string> processedFieldNames = new HashSet <string>();
            // If we fill SectorWithPortalAndCountry and join Name_DbContent, we have 2 times Id in the fields, but the second Id is the Id of the DbContent, not the one of the Sector
            var source = Expression.Variable(typeof(IDataRecord), "source");

            for (int i = 0; i < reader.FieldCount; i++)
            {
                string fieldName = reader.GetName(i).Replace(" ", ""); // Handle columns whose name contains a whitespace
                if (!processedFieldNames.Contains(fieldName))
                {
                    processedFieldNames.Add(fieldName);
                    PropertyInfo propertyInfo = type.GetProperty(
                        fieldName,
                        BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.SetField);

                    if (propertyInfo?.GetSetMethod() != null)
                    {
                        Expression getValue;
                        if (propertyInfo.PropertyType == typeof(SqlXml))
                        {
                            getValue = Expression.Call(source, DynamicLoadHelpers.GetSqlXmlMethod, Expression.Constant(i));
                        }
                        else if (propertyInfo.PropertyType == typeof(decimal))
                        {
                            getValue = Expression.Call(null, DynamicLoadHelpers.GetDecimalMethodInfo, source, Expression.Constant(i));
                        }
                        else if (propertyInfo.PropertyType == typeof(decimal?))
                        {
                            getValue = Expression.Call(null, DynamicLoadHelpers.GetNullableDecimalMethodInfo, source, Expression.Constant(i));
                        }
                        else if (IdTypeExtension.IsIdType(propertyInfo.PropertyType))
                        {
                            getValue = Expression.Call(DynamicLoadHelpers.GetIdParameterMethodInfo, source, Expression.Constant(i));
                            var constructor = propertyInfo.PropertyType.GetConstructor(new[] { typeof(int) });
                            getValue = Expression.New(constructor, getValue);
                        }
                        else if (IdTypeExtension.IsNullableIdType(propertyInfo.PropertyType))
                        {
                            var methodInfo = propertyInfo.PropertyType.GetGenericArguments()[0].GetMethod("Nullable", new[] { typeof(int?) });
                            getValue = Expression.Call(null, methodInfo, Expression.Call(null, DynamicLoadHelpers.GetNullableIntMethodInfo, source, Expression.Constant(i)));
                        }
                        else if (LongIdTypeExtension.IsLongIdType(propertyInfo.PropertyType))
                        {
                            getValue = Expression.Call(DynamicLoadHelpers.GetLongIdParameterMethodInfo, source, Expression.Constant(i));

                            var constructor = propertyInfo.PropertyType.GetConstructor(new[] { typeof(long) });
                            getValue = Expression.New(constructor, getValue);
                        }
                        else if (LongIdTypeExtension.IsNullableLongIdType(propertyInfo.PropertyType))
                        {
                            var methodInfo = propertyInfo.PropertyType.GetGenericArguments()[0].GetMethod("Nullable", new[] { typeof(long?) });
                            getValue = Expression.Call(null, methodInfo, Expression.Call(null, DynamicLoadHelpers.GetNullableLongMethodInfo, source, Expression.Constant(i)));
                        }
                        else
                        {
                            getValue = Expression.Call(source, getValueMethod, Expression.Constant(i));
                            if (propertyInfo.PropertyType == typeof(XElement))
                            {
                                getValue = Expression.Call(null, DynamicLoadHelpers.LoadXElement, getValue);
                            }
                            else if (propertyInfo.PropertyType == typeof(Binary))
                            {
                                // Need this to convert byte[] to Binary
                                getValue = Expression.Call(null, DynamicLoadHelpers.GetBinaryMethodInfo, source, Expression.Constant(i));
                            }
                            else if (!propertyInfo.PropertyType.IsValueType &&
                                     propertyInfo.PropertyType != typeof(string))
                            {
                                // generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i));
                                // NL 05.01.2009: Use this line below instead of the one above; otherwise, when there comes an int from the dataRecord,
                                // but the target object expects an int?, this int? is then 0 ... don't know what this Unbox_Any does exactly... :-/
                                getValue = Expression.Unbox(getValue, propertyInfo.PropertyType);
                            }
                        }

                        if (propertyInfo.PropertyType == typeof(Date) ||
                            propertyInfo.PropertyType == typeof(Date?))
                        {
                            getValue = Expression.Convert(getValue, typeof(DateTime?));
                        }

                        getValue = Expression.Convert(getValue, propertyInfo.PropertyType);
                        var assignment = Expression.Assign(Expression.Property(dest, propertyInfo), getValue);
                        var expression = Expression.IfThen(
                            Expression.IsFalse(
                                Expression.Call(source, DynamicLoadHelpers.IsDBNullMethodInfo, Expression.Constant(i))),
                            assignment);

                        body.Add(expression);

                        propertyCount++;
                    }
                }
            }

            body.Add(dest);

            var expr = Expression.Lambda <Func <IDataRecord, object> >(Expression.Block(new[] { dest }, body.ToArray()), source);

            return(expr.Compile());
        }