예제 #1
0
        /// <summary>
        ///     Fluent syntax for defining a property mapping. Use in the constructor.
        /// </summary>
        /// <typeparam name="TProperty">The type of the property.</typeparam>
        /// <param name="propertyExpression">The property expression.</param>
        /// <returns>mapping to configure.</returns>
        public FluentPropertyMapping <TEntity, TProperty> Property <TProperty>(Expression <Func <TEntity, TProperty> > propertyExpression)
        {
            var propertyInfo = propertyExpression.GetPropertyInfo();

            if (_mappings.ContainsKey(propertyInfo.Name))
            {
                return(new FluentPropertyMapping <TEntity, TProperty>((PropertyMapping <TEntity>)_mappings[propertyInfo.Name]));
            }

            var setter  = BuildSetter(typeof(TEntity), propertyInfo);
            var getter  = BuildGetter(typeof(TEntity), propertyInfo);
            var mapping = new PropertyMapping <TEntity>(propertyInfo.Name, setter, getter)
            {
                PropertyType = propertyInfo.PropertyType
            };

            _mappings.Add(propertyInfo.Name, mapping);
            return(new FluentPropertyMapping <TEntity, TProperty>(mapping));
        }
예제 #2
0
        private void MapProperties(Type type)
        {
            var properties =
                typeof(TEntity).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            foreach (var property in properties)
            {
                var method = property.GetSetMethod(true);
                Action <TEntity, object> setter;
                if (method == null)
                {
                    var field = type.GetField("_" + char.ToLower(property.Name[0]) + property.Name.Substring(1),
                                              BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
                    if (field == null)
                    {
                        continue;
                    }

                    var instance = Expression.Parameter(typeof(TEntity), "instance");
                    var value    = Expression.Parameter(typeof(object), "value");
                    var result   =
                        Expression.Lambda <Action <TEntity, object> >(
                            Expression.Assign(
                                Expression.Field(instance, field),
                                Expression.Convert(value, field.FieldType)),
                            instance,
                            value).Compile();

                    setter = result;
                }
                else
                {
                    var instance   = Expression.Parameter(typeof(TEntity), "i");
                    var argument   = Expression.Parameter(typeof(object), "a");
                    var setterCall = Expression.Call(
                        instance,
                        method,
                        Expression.Convert(argument, property.PropertyType));
                    var result = (Action <TEntity, object>)Expression.Lambda(setterCall, instance, argument)
                                 .Compile();


                    //var m = method;
                    //setter = (instance, value) => m.Invoke(instance, new[] { value });
                    setter = result;
                }

                method = property.GetGetMethod(true);
                Func <TEntity, object> getter;
                if (method == null)
                {
                    var field = type.GetField("_" + char.ToLower(property.Name[0]) + property.Name.Substring(1),
                                              BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
                    if (field == null)
                    {
                        continue;
                    }

                    //getter = field.GetValue;
                    var        paramExpression = Expression.Parameter(typeof(TEntity), "instance");
                    Expression fieldGetter     = Expression.Field(paramExpression, field.Name);
                    if (field.FieldType.IsPrimitive)
                    {
                        fieldGetter = Expression.Convert(fieldGetter, typeof(object));
                    }

                    var result =
                        Expression.Lambda <Func <TEntity, object> >(fieldGetter, paramExpression).Compile();
                    getter = result;
                }
                else
                {
                    //var m = method;
                    //getter = (instance) => m.Invoke(instance, null);

                    var instance = Expression.Parameter(typeof(TEntity), "i");
                    var prop     = Expression.Property(instance, property);
                    var convert  = Expression.TypeAs(prop, typeof(object));
                    var result   = (Func <TEntity, object>)Expression.Lambda(convert, instance).Compile();
                    getter = result;
                }

                var mapping = new PropertyMapping <TEntity>(property.Name, setter, getter);
                _mappings.Add(property.Name, mapping);
            }
        }