Beispiel #1
0
        private Expression VisitMapContextCall(MethodCallExpression node)
        {
            switch (node.Method.Name)
            {
            case "Map": {
                var inPrm   = node.Arguments[0];
                var inType  = inPrm.Type;
                var outType = node.Method.ReturnType;

                if (_includes != null && !CheckInclude(inPrm))
                {
                    return(Expression.Default(outType));
                }

                var mapDefinition = _mapConfiguration.GetMapDefinition(inType, outType);
                var projector     = mapDefinition.Projector;
                var oldInPrm      = projector.Parameters[0];

                var memberInit    = (MemberInitExpression)projector.Body;
                var replaceParams = new Dictionary <ParameterExpression, Expression> {
                    { oldInPrm, inPrm }
                };
                var parameterReplaceVisitor = new ParameterReplaceVisitor(replaceParams);

                return(Visit(parameterReplaceVisitor.Visit(memberInit)));
            }

            case "MapToList": {
                var retType = node.Method.ReturnType;
                var inPrm   = node.Arguments[0];
                var genPrms = node.Method.GetGenericArguments();
                var inType  = genPrms[0];
                var outType = genPrms[1];

                IncludePath memberIncludePath = null;
                if (_includes != null && !TryGetIncludePath(inPrm, out memberIncludePath))
                {
                    return(Expression.Default(retType));
                }

                var mapDefinition = _mapConfiguration.GetMapDefinition(inType, outType);
                var subValue      = new ProjectionVisitor(_mapConfiguration, memberIncludePath?.Children).VisitProjector(mapDefinition.Projector);
                var methodName    = node.Method.Name.Substring(3);
                var subProjector  = Expression.Call(typeof(Enumerable), "Select", new[] {
                        node.Method.GetGenericArguments()[0],
                        node.Method.GetGenericArguments()[1]
                    }, node.Arguments[0], subValue);

                return(Expression.Call(typeof(Enumerable), methodName, new[] { node.Method.ReturnType.GetGenericArguments()[0] }, subProjector));
            }

            default:
                throw new InvalidOperationException(
                          $"Projection does not support MapContext method '{node.Method.Name}', only 'Map' and 'MapToList' are supported."
                          );
            }
        }
Beispiel #2
0
        private IncludePath GetIncludePath(IEnumerable <string> path)
        {
            IncludePath include  = null;
            var         includes = _includes;

            foreach (var member in path)
            {
                include = includes.FirstOrDefault(i => i.Member == member);
                if (include == null)
                {
                    return(null);
                }

                includes = include.Children;
            }

            return(include);
        }
Beispiel #3
0
        private bool TryGetIncludePath(Expression memberExp, out IncludePath includePath)
        {
            includePath = null;

            var path     = Helper.GetMemberPath(memberExp);
            var includes = _includes;

            foreach (var member in path)
            {
                includePath = includes.FirstOrDefault(i => i.Member == member);
                if (includePath == null)
                {
                    return(false);
                }

                includes = includePath.Children;
            }

            return(true);
        }
Beispiel #4
0
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            if (node.Method.DeclaringType == typeof(MapContext) && node.Method.Name == "Map")
            {
                var inPrm   = node.Arguments[0];
                var inType  = inPrm.Type;
                var outType = node.Method.ReturnType;

                if (_includes != null)
                {
                    var path = Helper.GetMemberPath(inPrm as MemberExpression);
                    if (path.Any() && GetIncludePath(path) == null)
                    {
                        return(Expression.Default(outType));
                    }
                }

                var mapDefinition = _mapConfiguration.GetMapDefinition(inType, outType);
                var projector     = mapDefinition.Projector;
                var oldInPrm      = projector.Parameters[0];

                var memberInit    = (MemberInitExpression)projector.Body;
                var replaceParams = new Dictionary <ParameterExpression, Expression> {
                    { oldInPrm, inPrm }
                };
                var parameterReplaceVisitor = new ParameterReplaceVisitor(replaceParams);
                return(base.Visit(parameterReplaceVisitor.Visit(memberInit)));
            }
            else if (node.Method.DeclaringType == typeof(MapContext) && node.Method.Name == "MapToList")
            {
                var retType = node.Method.ReturnType;
                var inPrm   = node.Arguments[0];
                var genPrms = node.Method.GetGenericArguments();
                var inType  = genPrms[0];
                var outType = genPrms[1];

                IncludePath memberIncludePath = null;
                if (_includes != null)
                {
                    memberIncludePath = GetIncludePath(Helper.GetMemberPath(inPrm as MemberExpression));
                    if (memberIncludePath == null)
                    {
                        return(Expression.Default(retType));
                    }
                }

                var mapDefinition = _mapConfiguration.GetMapDefinition(inType, outType);
                var subValue      = new ProjectionVisitor(_mapConfiguration, memberIncludePath?.Children).VisitProjector(mapDefinition.Projector);
                var subProjector  = Expression.Call(typeof(Enumerable), "Select", new Type[] {
                    node.Method.GetGenericArguments()[0],
                    node.Method.GetGenericArguments()[1]
                }, node.Arguments[0], subValue);
                return(Expression.Call(typeof(Enumerable), "ToList", new Type[] { node.Method.ReturnType.GetGenericArguments()[0] }, subProjector));
            }
            else if (node.Method.DeclaringType == typeof(Enumerable) && node.Method.Name == "ToList")
            {
                var retType = node.Method.ReturnType;

                var subNode = node.Arguments[0] as MethodCallExpression;
                if (subNode != null && subNode.Method.DeclaringType == typeof(Enumerable) && subNode.Method.Name == "Select")
                {
                    var inPrm = subNode.Arguments[0];

                    IncludePath memberIncludePath = null;
                    if (_includes != null)
                    {
                        memberIncludePath = GetIncludePath(Helper.GetMemberPath(inPrm as MemberExpression));
                        if (memberIncludePath == null)
                        {
                            return(Expression.Default(retType));
                        }
                    }

                    var subValue     = new ProjectionVisitor(_mapConfiguration, memberIncludePath?.Children).Visit(subNode.Arguments[1]);
                    var subProjector = Expression.Call(typeof(Enumerable), "Select", new Type[] {
                        subNode.Method.GetGenericArguments()[0],
                        subNode.Method.GetGenericArguments()[1]
                    }, subNode.Arguments[0], subValue);
                    return(Expression.Call(typeof(Enumerable), "ToList", new Type[] { node.Method.ReturnType.GetGenericArguments()[0] }, subProjector));
                }
            }

            return(base.VisitMethodCall(node));
        }