/// <summary>
        /// Creates an <see cref="Expression{TDelegate}"/> that
        /// produces an instance of <typeparamref name="T"/> based an a <see cref="IDataRecord"/>.
        /// </summary>
        /// <param name="dataRecord">The <see cref="IDataRecord"/> that represents the available fields/columns.</param>
        /// <returns>An <see cref="Expression{TDelegate}"/> that represents creating an instance of <typeparamref name="T"/>.</returns>
        public Expression <Func <IDataRecord, T> > CreateExpression(IDataRecord dataRecord)
        {
            int[] ordinals = ordinalSelector.Execute(typeof(T), dataRecord);
            Func <IDataRecord, int[], T> createInstanceMethod = propertyMapperDelegateBuilder.CreateMethod(typeof(T));
            var ordinalsExpression                   = Expression.Constant(ordinals, typeof(int[]));
            var createInstanceMethodExpression       = Expression.Constant(createInstanceMethod, typeof(Func <IDataRecord, int[], T>));
            ParameterExpression datarecordExpression = Expression.Parameter(typeof(IDataRecord), "dataRecord");
            var invokeExpression = Expression.Invoke(createInstanceMethodExpression, new Expression[] { datarecordExpression, ordinalsExpression });
            ParameterExpression instanceExpression = Expression.Variable(typeof(T), "instance");
            BinaryExpression    assignExpression   = Expression.Assign(instanceExpression, invokeExpression);
            Expression <Action <IDataRecord, T> > manyToOneExpression = manyToOneExpressionBuilder.CreateExpression <T>(dataRecord);
            BlockExpression blockExpression;

            if (manyToOneExpression != null)
            {
                blockExpression = Expression.Block(new[] { instanceExpression }, assignExpression, CreateInvocationExpression(manyToOneExpression, datarecordExpression, instanceExpression), instanceExpression);
            }
            else
            {
                blockExpression = Expression.Block(new[] { instanceExpression }, assignExpression);
            }

            var lambda = Expression.Lambda <Func <IDataRecord, T> >(blockExpression, new[] { datarecordExpression });

            return(lambda);
        }
Exemple #2
0
 /// <summary>
 /// Executes the selector and returns the ordinals required to read the columns from the data record.
 /// </summary>
 /// <param name="type">The <see cref="Type"/> for which to return the ordinals.</param>
 /// <param name="dataRecord">The <see cref="IDataRecord"/> that represents the available fields/columns.</param>
 /// <returns>A list of ordinals.</returns>
 public int[] Execute(Type type, IDataRecord dataRecord)
 {
     return(cache.GetOrAdd(type, t => ordinalSelector.Execute(t, dataRecord)));
 }