Exemplo n.º 1
0
        static LambdaExpression CreateMappingLambda(Type typeT, List <Mapping <Thing, Thing> > mapping)
        {
            var result          = Expression.Parameter(typeof(SqlDataRecord), "rec");
            var metaDataParam   = Expression.Parameter(typeof(SqlMetaData[]), "metaData");
            var item            = Expression.Parameter(typeT, "item");
            var constructorInfo = typeof(SqlDataRecord).GetConstructor(new[] { typeof(SqlMetaData[]) });
            var lines           = new List <Expression>
            {
                Expression.Assign(result, Expression.New(constructorInfo, metaDataParam))
            };
            var propertiesAndFields = Types.ReadablePropertiesAndFieldsDictionary(typeT);

            var setNullMethod = typeof(SqlDataRecord).GetMethod("SetDBNull", new[] { typeof(int) });

            Contract.Assert(setNullMethod != null);

            foreach (var map in mapping)
            {
                var col         = (Column)map.To;
                var setValueExp = SetValue(result, item, map.From, col);
                if (setValueExp == null)
                {
                    continue;
                }

                if (Types.CanBeNull(map.From.Type))
                {
                    lines.Add(Expression.IfThenElse(
                                  Expression.Equal(Expression.PropertyOrField(item, map.From.Name), Expression.Constant(null)),
                                  Expression.Call(result, setNullMethod, Expression.Constant(col.Ordinal)),
                                  setValueExp
                                  ));
                }
                else
                {
                    lines.Add(setValueExp);
                }
            }
            lines.Add(result);
            var block            = Expression.Block(new[] { result }, lines);
            var func             = typeof(Func <, ,>).MakeGenericType(typeof(SqlMetaData[]), typeT, typeof(SqlDataRecord));
            var lambdaExpression = Expression.Lambda(func, block, metaDataParam, item);

            return(lambdaExpression);
        }