/// <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> /// Creates a function delegate that returns a <see cref="IStructuralEquatable"/> instance, /// representing the key values for the given <paramref name="type"/>. /// </summary> /// <param name="type">The <see cref="Type"/> for which to build the delegate.</param> /// <param name="dataRecord">The <see cref="IDataRecord"/> containing the target fields/columns.</param> /// <returns>A function delegate used to retrieve key values for the given <paramref name="type"/>.</returns> public Func <IDataRecord, IStructuralEquatable> CreateKeyDelegate(Type type, IDataRecord dataRecord) { IEnumerable <PropertyMappingInfo> ordinals = propertyMapper.Execute(type, dataRecord); var keyOrdinal = GetValidPropertyMappingWithTheSmallestOrdinal(ordinals); if (keyOrdinal == null) { return(null); } Type keyType = typeof(Tuple <>).MakeGenericType(keyOrdinal.Property.PropertyType); var keyMethod = keyInstanceEmitter.CreateMethod(keyType); return(dr => keyMethod(dr, new[] { keyOrdinal.Ordinal })); }
/// <summary> /// Creates a new method used to populate an object from an <see cref="IDataRecord"/>. /// </summary> /// <param name="type">The target type for which to create the dynamic method.s</param> /// <returns>An function delegate used to invoke the method.</returns> public Func <IDataRecord, int[], T> CreateMethod(Type type) { return(cache.GetOrAdd(type, t => mapperDelegateBuilder.CreateMethod(t))); }