コード例 #1
0
        /// <summary>
        /// Generate the method body for reading a IDataReader
        /// </summary>
        static Expression GenerateMethodBody(Expression reader, ValueMapping mapping)
        {
            var br       = Expression.Label("break");
            var itemType = (mapping is ValueMapping typed ? typed.Type : typeof(object));
            var listType = typeof(List <>).MakeGenericType(itemType);

            var list     = Expression.Variable(listType, "items");
            var listInit = Expression.Assign(list, Expression.New(listType));

            var loopCond = Expression.IfThen(
                Expression.Not(Expression.Call(reader, "Read", new Type[0])),
                Expression.Break(br)
                );

            var loop = Expression.Loop(
                Expression.Block(
                    loopCond,
                    GenerateLoopBody(reader, list, mapping)
                    )
                , br);

            var body = Expression.Block(
                new ParameterExpression[] { list },
                new Expression[] { listInit,
                                   loop,
                                   list }
                );

            return(body);
        }
コード例 #2
0
        /// <summary>
        /// Generate an expression for a given mapping
        /// </summary>
        static Expression GenerateMapping(Expression reader, ValueMapping mapping)
        {
            switch (mapping)
            {
            case SingularMapping singular:
                return(GenerateSingularMapping(reader, singular));

            case CtorMapping ctor:
                return(GenerateCtorMapping(reader, ctor));

            case NullMapping _:
                throw new ArgumentException($"No mapping found between data reader columns and type '{mapping.Type}'");

            default:
                throw new ArgumentException();
            }
        }
コード例 #3
0
        /// <summary>
        /// Generate a method that takes a data reader and return a list of readed items
        /// </summary>
        /// <typeparam name="TReader">Specific reader type</typeparam>
        /// <typeparam name="TItem">Row type</typeparam>
        /// <param name="mapping">Constructor mapping</param>
        public static Expression <Func <TReader, List <TItem> > > GenerateReaderMethod <TReader, TItem>(ValueMapping mapping)
        {
            var readerType = typeof(TReader);

            if (readerType.IsInterface)
            {
                throw new ArgumentException("Pass an specific reader type");
            }
            var readerArg = Expression.Parameter(readerType, "reader");
            var body      = GenerateMethodBody(readerArg, mapping);

            return(Expression.Lambda <Func <TReader, List <TItem> > >(body, readerArg));
        }
コード例 #4
0
        public static Expression GenerateLoopBody(Expression reader, Expression list, ValueMapping mapping)
        {
            var itemType = (mapping is ValueMapping typed ? typed.Type : typeof(object));
            var body     = new List <Expression>();

            var itemVar = Expression.Variable(itemType, "item");

            body.Add(Expression.Assign(itemVar, GenerateMapping(reader, mapping)));
            body.Add(Expression.Call(list, "Add", new Type[0], itemVar));

            var ret = Expression.Block(
                new[] { itemVar },
                body.ToList()
                );

            return(ret);
        }