private void init()
            {
                var type       = typeof(T);
                var schema     = this._reader.GetSchemaTable();
                var columnOrds = schema.Rows
                                 .Cast <DataRow>()
                                 .Select(x => new
                {
                    Name    = x[0].ToString().Replace("[", "").Replace("]", "").Split('.')[1],
                    Ordianl = Convert.ToInt32(x[1])
                });

                var props = type.GetProperties()
                            .Where(x => System.Attribute.IsDefined(x, typeof(MapToAttribute)))
                            .Select(x => new
                {
                    Attribute    = x.GetCustomAttribute <MapToAttribute>(),
                    PropertyInfo = x
                })
                            .Join(columnOrds, p => p.Attribute.MdxColumn, co => co.Name, (p, co) => new
                {
                    Ordinal  = co.Ordianl,
                    Property = p
                })
                            .OrderBy(x => x.Property.Attribute.MdxColumn);

                this._ornials = props.Select(x => x.Ordinal).ToArray();

                var bindingList = new Dictionary <ParameterExpression, MemberAssignment>();

                this._converters = new TypeConverter[props.Count()];
                var stringArrayParam    = Expression.Parameter(typeof(string[]), "values");
                var converterArrayParam = Expression.Parameter(typeof(TypeConverter[]), "converters");
                var converter           = typeof(TypeConverter).GetMethod("ConvertFromString", new[] { typeof(string) });

                props.For((v, i) =>
                {
                    var prop                     = v.Property.PropertyInfo;
                    var paramExp                 = Expression.Parameter(prop.PropertyType, prop.Name);
                    var arrayAssignment          = Expression.ArrayIndex(stringArrayParam, Expression.Constant(i));
                    var typeConverter            = TypeDescriptor.GetConverter(prop.PropertyType);
                    var converterArrayAssignment = Expression.ArrayIndex(converterArrayParam, Expression.Constant(i));
                    var defaultValue             = prop.PropertyType.GetDefault();
                    var defaultConstant          = Expression.Constant(defaultValue == null ? null : defaultValue.ToString(), typeof(string));
                    var methodExp                = Expression.Call(converterArrayAssignment, converter, Expression.Coalesce(arrayAssignment, defaultConstant));

                    Expression.Bind(prop,
                                    Expression.Convert(methodExp, prop.PropertyType))
                    .Finally(bind => bindingList.Add(paramExp, bind));

                    this._converters[i] = typeConverter;
                });

                var newExp     = Expression.New(typeof(T));
                var memberInit = Expression.MemberInit(newExp, bindingList.Values.ToArray());
                var lambda     = Expression.Lambda <Creatorlator>(memberInit, new[] { converterArrayParam, stringArrayParam });

                this._creator = lambda.Compile();
            }
예제 #2
0
            void init()
            {
                var type   = typeof(T);
                var schema = _reader.GetSchemaTable();

                if (schema != null)
                {
                    var columnOrds = schema.Rows
                                     .Cast <DataRow>()
                                     .Select(x => new
                    {
                        Name    = x[0].ToString().Replace("[", "").Replace("]", ""),
                        Ordianl = Convert.ToInt32(x[1])
                    });

                    var props = type.GetProperties()
                                .Select(x => new
                    {
                        PropertyInfo = x
                    }).Join(columnOrds, a => a.PropertyInfo.Name, b => b.Name, (a, b) => new
                    {
                        Ordinal  = b.Ordianl,
                        Property = a
                    }).OrderBy(x => x.Ordinal);

                    _ornials = props.Select(x => x.Ordinal).ToArray();

                    var bindingList = new Dictionary <ParameterExpression, MemberAssignment>();
                    _converters = new TypeConverter[props.Count()];
                    var stringArrayParam    = Expression.Parameter(typeof(string[]), "values");
                    var converterArrayParam = Expression.Parameter(typeof(TypeConverter[]), "converters");
                    var converter           = typeof(TypeConverter).GetMethod("ConvertFromString", new[] { typeof(string) });

                    props.For((v, i) =>
                    {
                        var prop                     = v.Property.PropertyInfo;
                        var paramExp                 = Expression.Parameter(prop.PropertyType, prop.Name);
                        var arrayAssignment          = Expression.ArrayIndex(stringArrayParam, Expression.Constant(i));
                        var typeConverter            = TypeDescriptor.GetConverter(prop.PropertyType);
                        var converterArrayAssignment = Expression.ArrayIndex(converterArrayParam, Expression.Constant(i));
                        var defaultValue             = prop.PropertyType.GetDefault();
                        var defaultConstant          = Expression.Constant(defaultValue == null ? null : defaultValue.ToString(), typeof(string));
                        var methodExp                = Expression.Call(converterArrayAssignment, converter, Expression.Coalesce(arrayAssignment, defaultConstant));

                        Expression.Bind(prop,
                                        Expression.Convert(methodExp, prop.PropertyType))
                        .Finally(bind => bindingList.Add(paramExp, bind));

                        _converters[i] = typeConverter;
                    });

                    var newExp     = Expression.New(typeof(T));
                    var memberInit = Expression.MemberInit(newExp, bindingList.Values.ToArray());
                    var lambda     = Expression.Lambda <Creatorlator>(memberInit, new[] { converterArrayParam, stringArrayParam });
                    _creator = lambda.Compile();
                }
            }