public void Should_work()
        {
            var extraProperties = typeof(ExtraProduct).GetProperties().Except(typeof(Product).GetProperties()).Select(p => new PropertyDescription(p));
            var similarType     = ProxyGenerator.GetSimilarType(typeof(Product), extraProperties);

            similarType.Assembly().IsDynamic.ShouldBeTrue();
            var sourceProperties      = GetProperties(typeof(ExtraProduct));
            var similarTypeProperties = GetProperties(similarType);

            similarTypeProperties.SequenceEqual(sourceProperties).ShouldBeTrue();

            dynamic instance = Activator.CreateInstance(similarType);

            instance.Id   = 12;
            instance.Name = "John";
            instance.ECommercePublished = true;
            instance.Short = short.MaxValue;
            instance.Long  = long.MaxValue;
            var articles = new Article[] { new Article(), null, null };

            instance.Articles = articles;
            instance.Article  = articles[0];

            Assert.Equal(12, instance.Id);
            Assert.Equal("John", instance.Name);
            Assert.Equal(true, instance.ECommercePublished);
            Assert.Equal(short.MaxValue, instance.Short);
            Assert.Equal(long.MaxValue, instance.Long);
            Assert.Equal(articles, instance.Articles);
            Assert.Equal(articles[0], instance.Article);
        }
            public override QueryExpressions GetSubQueryExpression(ExpressionBuilder builder, Expression projection, TypeMap typeMap, ExpressionRequest request, Expression instanceParameter, TypePairCount typePairCount)
            {
                var letMapInfos = _savedPaths.Select(path =>
                                                     new {
                    path.LetExpression,
                    MapFromSource = path.GetSourceExpression(instanceParameter),
                    Property      = path.GetPropertyDescription(),
                    path.Marker
                }).ToArray();

                var properties = letMapInfos.Select(m => m.Property).Concat(GetMemberAccessesVisitor.Retrieve(projection, instanceParameter));

                var     letType = ProxyGenerator.GetSimilarType(typeof(object), properties);
                TypeMap letTypeMap;

                lock (ConfigurationProvider)
                {
                    letTypeMap = TypeMapFactory.CreateTypeMap(request.SourceType, letType, typeMap.Profile);
                }
                var secondParameter = Parameter(letType, "dtoLet");

                ReplaceSubQueries();

                var firstExpression = builder.CreateMapExpressionCore(request, instanceParameter, typePairCount, letTypeMap, base.New());

                return(new QueryExpressions(firstExpression, projection, secondParameter));

                void ReplaceSubQueries()
                {
                    foreach (var letMapInfo in letMapInfos)
                    {
                        var letProperty    = letType.GetProperty(letMapInfo.Property.Name);
                        var letPropertyMap = letTypeMap.FindOrCreatePropertyMapFor(letProperty);
                        letPropertyMap.CustomMapExpression = Lambda(letMapInfo.LetExpression.ReplaceParameters(letMapInfo.MapFromSource), secondParameter);
                        projection = projection.Replace(letMapInfo.Marker, MakeMemberAccess(secondParameter, letProperty));
                    }
                    projection = new ReplaceMemberAccessesVisitor(instanceParameter, secondParameter).Visit(projection);
                }
            }