/// <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); }
/// <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))); }