Пример #1
0
        private static Type Create(DataReaderCache cache)
        {
            TypeBuilder tb = _mb.DefineType(
                $"DynamicType_#{cache.GetColumnHash()}",
                TypeAttributes.Public);

            for (int fieldIndex = 0; fieldIndex < cache.Reader.FieldCount; fieldIndex++)
            {
                tb.DefineField(
                    cache.Reader.GetName(fieldIndex),
                    cache.Reader.GetFieldType(fieldIndex),
                    FieldAttributes.Public);
            }

            return(tb.CreateTypeInfo());
        }
Пример #2
0
        public static Type Get(DataReaderCache cache)
        {
            if (cache == null)
            {
                throw new ArgumentNullException(nameof(cache));
            }

            if (!_cache.TryGetValue(cache.GetColumnHash(), out Type value))
            {
                lock (_lock)
                {
                    if (!_cache.TryGetValue(cache.GetColumnHash(), out value))
                    {
                        value = Create(cache);
                        _cache.Add(cache.GetColumnHash(), value);
                    }
                }
            }

            return(value);
        }
Пример #3
0
        public static Func <IDataRecord, object> CreateMap(DataReaderCache cache)
        {
            if (cache == null)
            {
                throw new ArgumentNullException(nameof(cache));
            }

            if (!_maps.TryGetValue(cache.GetColumnHash(), out Func <IDataRecord, object> func))
            {
                lock (_lock)
                {
                    if (!_maps.TryGetValue(cache.GetColumnHash(), out func))
                    {
                        func = Create(cache);
                        _maps.Add(cache.GetColumnHash(), func);
                    }
                }
            }

            return(func);
        }
Пример #4
0
        public static Func <IDataRecord, T> Create(DataReaderCache cache)
        {
            if (cache == null)
            {
                throw new ArgumentNullException(nameof(cache));
            }

            if (!_cache.TryGetValue(cache.GetColumnHash(), out Func <IDataRecord, T> func))
            {
                lock (_lock)
                {
                    if (!_cache.TryGetValue(cache.GetColumnHash(), out func))
                    {
                        func = CreateHelper(cache.Reader);
                        _cache.Add(cache.GetColumnHash(), func);
                    }
                }
            }

            return(func);
        }
Пример #5
0
        private static Func <IDataRecord, object> Create(DataReaderCache cache)
        {
            Type instanceType = DynamicType.Get(cache);

            var instance = Expression.Variable(instanceType, "instance");
            var value    = Expression.Variable(typeof(object), "value");
            var record   = Expression.Parameter(typeof(IDataRecord), "record");

            var expressions = new List <Expression>
            {
                Expression.Assign(instance, Expression.New(instanceType))
            };

            for (var fieldIndex = 0; fieldIndex < cache.Reader.FieldCount; fieldIndex++)
            {
                var fieldName = cache.Reader.GetName(fieldIndex);
                var fieldType = cache.Reader.GetFieldType(fieldIndex);

                var getValueCall = Expression.Call(
                    record,
                    _getValueMethod,
                    Expression.Constant(fieldIndex));

                var isNotDbNull = Expression.NotEqual(
                    value,
                    Expression.Constant(DBNull.Value, typeof(object)));

                var memberExpression = Expression.MakeMemberAccess(
                    instance,
                    instanceType.GetField(fieldName));

                var setCall = Expression.Assign(
                    memberExpression,
                    Expression.Convert(value, fieldType));

                // Get the Value
                expressions.Add(Expression.Assign(
                                    value,
                                    getValueCall));

                // Only bother setting the value if is not dbnull,
                // otherwise let the field stay at the default value
                expressions.Add(Expression.IfThen(
                                    isNotDbNull,
                                    setCall));
            }

            var labelTarget     = Expression.Label(typeof(object));
            var labelExpression = Expression.Label(labelTarget, Expression.Default(typeof(object)));

            expressions.Add(Expression.Return(
                                labelTarget,
                                Expression.Convert(instance, typeof(object))));

            expressions.Add(labelExpression);

            BlockExpression block = Expression.Block(
                new[] { instance, value },
                expressions);

            var lambda = Expression.Lambda <Func <IDataRecord, object> >(
                block,
                record);

            return(lambda.Compile());
        }