Ejemplo n.º 1
0
        private Expression BuildWriterItem(IMappingAssociation association, Expression from, Expression to, ParameterExpression explicitProperties)
        {
            if ((association.Direction & MappingDirection.Write) != MappingDirection.Write)
            {
                return(null);
            }

            var converter = association as IConvertionAssociation;
            var component = association as IComponentAssociation;

            var donor    = association.Target.Apply(@from);
            var acceptor = association.Source.Apply(to);

            Expression result;

            if (component != null)
            {
                //todo: probably should filterout expand somehow. E.g. 'foo.id' should become 'id'. Now simply not passing outer expand
                result = BuildWriterBody(donor, acceptor, null);

                if (result.NodeType == ExpressionType.Default && result.Type == typeof(void))
                {
                    return(null);
                }
            }
            else
            {
                PropertyInfo prop;
                if (!acceptor.TryGetProperty(out prop))
                {
                    throw new InvalidOperationException(
                              string.Format("Mapping from source:{0} to target:{1} marked as writable but source is not a property access expression", association.Source.Stringify(), association.Target.Stringify())
                              );
                }

                result = Expression.Assign(
                    acceptor,
                    converter == null ? donor : converter.TargetConverter.Expression.Apply(donor)
                    );
            }

            if (!(donor.Type.IsValueType || (result.NodeType == ExpressionType.Assign && ((BinaryExpression)result).Right == donor)))
            {
                result = Expression.IfThenElse(
                    donor.CreateCheckForDefault(),
                    Expression.Assign(acceptor, acceptor.Type.GetDefaultExpression()),
                    result
                    );
            }

            if (explicitProperties != null)
            {
                result = Expression.IfThen(
                    Expression.OrElse(
                        explicitProperties.CreateCheckForDefault(),
                        explicitProperties.CreateContains(Expression.Constant(association.Key, typeof(string)))
                        ),
                    result
                    );
            }

            return(result);
        }