public void Bind_GeneratedExpression_ContainsExpandedObject()
        {
            // Arrange
            SelectExpandQueryOption selectExpand = new SelectExpandQueryOption("Orders", "Orders,Orders($expand=Customer)", _context);
            IPropertyMapper         mapper       = new IdentityPropertyMapper();

            _model.Model.SetAnnotationValue(_model.Order, new DynamicPropertyDictionaryAnnotation(typeof(Order).GetProperty("OrderProperties")));

            // Act
            IQueryable queryable = SelectExpandBinder.Bind(_queryable, _settings, new DefaultAssembliesResolver(), selectExpand);

            // Assert
            IEnumerator enumerator = queryable.GetEnumerator();

            Assert.True(enumerator.MoveNext());
            var partialCustomer = Assert.IsAssignableFrom <SelectExpandWrapper <Customer> >(enumerator.Current);

            Assert.False(enumerator.MoveNext());
            Assert.Null(partialCustomer.Instance);
            IEnumerable <SelectExpandWrapper <Order> > innerOrders = partialCustomer.Container
                                                                     .ToDictionary(mapper)["Orders"] as IEnumerable <SelectExpandWrapper <Order> >;

            Assert.NotNull(innerOrders);
            SelectExpandWrapper <Order> partialOrder = innerOrders.Single();

            Assert.Same(_queryable.First().Orders.First(), partialOrder.Instance);
            object customer = partialOrder.Container.ToDictionary(mapper)["Customer"];
            SelectExpandWrapper <Customer> innerInnerCustomer = Assert.IsAssignableFrom <SelectExpandWrapper <Customer> >(customer);

            Assert.Same(_queryable.First(), innerInnerCustomer.Instance);
        }
        public void Bind_GeneratedExpression_ContainsExpandedObject()
        {
            // Arrange
            SelectExpandQueryOption selectExpand = new SelectExpandQueryOption("Orders", "Orders,Orders($expand=Customer)", _context);
            IPropertyMapper mapper = new IdentityPropertyMapper();
            _model.Model.SetAnnotationValue(_model.Order, new DynamicPropertyDictionaryAnnotation(typeof(Order).GetProperty("OrderProperties")));

            // Act
            IQueryable queryable = SelectExpandBinder.Bind(_queryable, _settings, new DefaultAssembliesResolver(), selectExpand);

            // Assert
            IEnumerator enumerator = queryable.GetEnumerator();
            Assert.True(enumerator.MoveNext());
            var partialCustomer = Assert.IsAssignableFrom<SelectExpandWrapper<Customer>>(enumerator.Current);
            Assert.False(enumerator.MoveNext());
            Assert.Null(partialCustomer.Instance);
            IEnumerable<SelectExpandWrapper<Order>> innerOrders = partialCustomer.Container
                .ToDictionary(mapper)["Orders"] as IEnumerable<SelectExpandWrapper<Order>>;
            Assert.NotNull(innerOrders);
            SelectExpandWrapper<Order> partialOrder = innerOrders.Single();
            Assert.Same(_queryable.First().Orders.First(), partialOrder.Instance);
            object customer = partialOrder.Container.ToDictionary(mapper)["Customer"];
            SelectExpandWrapper<Customer> innerInnerCustomer = Assert.IsAssignableFrom<SelectExpandWrapper<Customer>>(customer);
            Assert.Same(_queryable.First(), innerInnerCustomer.Instance);
        }
        public void Bind_GeneratedExpression_DelegateCachingEnabled()
        {
            // Arrange
            SelectExpandQueryOption selectExpand = new SelectExpandQueryOption("Orders", "Orders,Orders($expand=Customer)", _context);
            IPropertyMapper         mapper       = new IdentityPropertyMapper();

            _model.Model.SetAnnotationValue(_model.Order, new DynamicPropertyDictionaryAnnotation(typeof(Order).GetProperty("OrderProperties")));
            var oldCacheExpirationTime = _settings.SelectExpandCacheExpirationTimeSeconds;

            SelectExpandBinder.ResetCache();
            _settings.SelectExpandCacheExpirationTimeSeconds = 10;

            // Act
            object result = SelectExpandBinder.Bind(_customer, _settings, selectExpand);

            // Assert
            Assert.Equal(SelectExpandBinder.DelegateCache.GetCount(), 1);
            KeyValuePair <string, object> cachedKeyValuePair = SelectExpandBinder.DelegateCache.First();

            Assert.IsAssignableFrom(typeof(Delegate), cachedKeyValuePair.Value);

            // Cleanup
            _settings.SelectExpandCacheExpirationTimeSeconds = oldCacheExpirationTime;
            SelectExpandBinder.ResetCache();
        }
        public void ProjectAsWrapper_NullExpandedProperty_HasNullValueInProjectedWrapper()
        {
            // Arrange
            IPropertyMapper mapper = new IdentityPropertyMapper();
            Order           order  = new Order();
            ExpandedNavigationSelectItem expandItem = new ExpandedNavigationSelectItem(
                new ODataExpandPath(new NavigationPropertySegment(_model.Order.NavigationProperties().Single(), navigationSource: _model.Customers)),
                _model.Customers,
                selectExpandOption: null);
            SelectExpandClause selectExpand = new SelectExpandClause(new SelectItem[] { expandItem }, allSelected: true);
            Expression         source       = Expression.Constant(order);

            // Act
            Expression projection = _binder.ProjectAsWrapper(source, selectExpand, _model.Order);

            // Assert
            SelectExpandWrapper <Order> projectedOrder = Expression.Lambda(projection).Compile().DynamicInvoke() as SelectExpandWrapper <Order>;

            Assert.NotNull(projectedOrder);
            Assert.Contains("Customer", projectedOrder.Container.ToDictionary(mapper).Keys);
            Assert.Null(projectedOrder.Container.ToDictionary(mapper)["Customer"]);
        }
        public void ProjectAsWrapper_NullExpandedProperty_HasNullValueInProjectedWrapper()
        {
            // Arrange
            IPropertyMapper mapper = new IdentityPropertyMapper();
            Order order = new Order();
            ExpandedNavigationSelectItem expandItem = new ExpandedNavigationSelectItem(
                new ODataExpandPath(new NavigationPropertySegment(_model.Order.NavigationProperties().Single(), navigationSource: _model.Customers)),
                _model.Customers,
                selectExpandOption: null);
            SelectExpandClause selectExpand = new SelectExpandClause(new SelectItem[] { expandItem }, allSelected: true);
            Expression source = Expression.Constant(order);
            _model.Model.SetAnnotationValue(_model.Order, new DynamicPropertyDictionaryAnnotation(typeof(Order).GetProperty("OrderProperties")));

            // Act
            Expression projection = _binder.ProjectAsWrapper(source, selectExpand, _model.Order);

            // Assert
            SelectExpandWrapper<Order> projectedOrder = Expression.Lambda(projection).Compile().DynamicInvoke() as SelectExpandWrapper<Order>;
            Assert.NotNull(projectedOrder);
            Assert.Contains("Customer", projectedOrder.Container.ToDictionary(mapper).Keys);
            Assert.Null(projectedOrder.Container.ToDictionary(mapper)["Customer"]);
        }