Example #1
0
        public void HasSinglePath_AddBindindPath_Derived(bool required, bool contained)
        {
            // Assert
            ODataModelBuilder builder = new ODataModelBuilder();
            var customerType          = builder.EntityType <BindingCustomer>();
            var navigationSource      = builder.EntitySet <BindingCustomer>("Customers");

            StructuralTypeConfiguration addressType = builder.StructuralTypes.FirstOrDefault(c => c.Name == "BindingAddress");

            Assert.Null(addressType);              // Guard
            Assert.Empty(customerType.Properties); // Guard

            // Act
            var binding    = new BindingPathConfiguration <BindingCustomer>(builder, customerType, navigationSource.Configuration);
            var newBinding = binding.HasSinglePath((BindingVipCustomer v) => v.VipLocation, required, contained);

            // Assert
            addressType = builder.StructuralTypes.FirstOrDefault(c => c.Name == "BindingAddress");
            Assert.NotNull(addressType);
            Assert.Empty(customerType.Properties);

            StructuralTypeConfiguration vipCustomerType = builder.StructuralTypes.FirstOrDefault(c => c.Name == "BindingVipCustomer");

            Assert.NotNull(vipCustomerType);
            var vipLocationProperty = Assert.Single(vipCustomerType.Properties);

            Assert.Equal("VipLocation", vipLocationProperty.Name);

            if (contained)
            {
                Assert.Equal(EdmTypeKind.Entity, addressType.Kind);
                Assert.Equal(PropertyKind.Navigation, vipLocationProperty.Kind);
                NavigationPropertyConfiguration navigationProperty = Assert.IsType <NavigationPropertyConfiguration>(vipLocationProperty);
                if (required)
                {
                    Assert.Equal(EdmMultiplicity.One, navigationProperty.Multiplicity);
                }
                else
                {
                    Assert.Equal(EdmMultiplicity.ZeroOrOne, navigationProperty.Multiplicity);
                }

                Assert.True(navigationProperty.ContainsTarget);
            }
            else
            {
                Assert.Equal(EdmTypeKind.Complex, addressType.Kind);
                Assert.Equal(PropertyKind.Complex, vipLocationProperty.Kind);
                ComplexPropertyConfiguration complexProperty = Assert.IsType <ComplexPropertyConfiguration>(vipLocationProperty);
                Assert.Equal(!required, complexProperty.OptionalProperty);
                Assert.Equal(typeof(BindingAddress), complexProperty.RelatedClrType);
            }

            // different bindings
            Assert.NotSame(binding, newBinding);
            Assert.Equal("", binding.BindingPath);

            Assert.IsType <BindingPathConfiguration <BindingAddress> >(newBinding);
            Assert.Equal("System.Web.OData.Formatter.BindingVipCustomer/VipLocation", newBinding.BindingPath);
        }
Example #2
0
        public virtual ComplexPropertyConfiguration AddComplexProperty(PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
            {
                throw Error.ArgumentNull("propertyInfo");
            }

            if (!propertyInfo.ReflectedType.IsAssignableFrom(ClrType))
            {
                throw Error.Argument("propertyInfo", SRResources.PropertyDoesNotBelongToType, propertyInfo.Name, ClrType.FullName);
            }

            if (propertyInfo.PropertyType == ClrType)
            {
                throw Error.Argument("propertyInfo", SRResources.RecursiveComplexTypesNotAllowed, ClrType.FullName, propertyInfo.Name);
            }

            if (propertyInfo.PropertyType == typeof(DateTime) || propertyInfo.PropertyType == typeof(DateTime?))
            {
                throw Error.Argument("propertyInfo", SRResources.DateTimeTypePropertyNotSupported,
                    propertyInfo.PropertyType.FullName, propertyInfo.Name, propertyInfo.DeclaringType.FullName,
                    typeof(DateTimeOffset).FullName, typeof(ODataModelBuilder).FullName);
            }

            ValidatePropertyNotAlreadyDefinedInBaseTypes(propertyInfo);
            ValidatePropertyNotAlreadyDefinedInDerivedTypes(propertyInfo);

            // Remove from the ignored properties
            if (RemovedProperties.Contains(propertyInfo))
            {
                RemovedProperties.Remove(propertyInfo);
            }

            ComplexPropertyConfiguration propertyConfiguration = null;
            if (ExplicitProperties.ContainsKey(propertyInfo))
            {
                propertyConfiguration = ExplicitProperties[propertyInfo] as ComplexPropertyConfiguration;
                if (propertyConfiguration == null)
                {
                    throw Error.Argument("propertyInfo", SRResources.MustBeComplexProperty, propertyInfo.Name, ClrType.FullName);
                }
            }
            else
            {
                propertyConfiguration = new ComplexPropertyConfiguration(propertyInfo, this);
                ExplicitProperties[propertyInfo] = propertyConfiguration;
                // Make sure the complex type is in the model.

                ModelBuilder.AddComplexType(propertyInfo.PropertyType);
            }

            return propertyConfiguration;
        }
Example #3
0
        private ComplexPropertyConfiguration GetComplexPropertyConfiguration(Expression propertyExpression, bool optional = false)
        {
            PropertyInfo propertyInfo             = PropertySelectorVisitor.GetSelectedProperty(propertyExpression);
            ComplexPropertyConfiguration property = _configuration.AddComplexProperty(propertyInfo);

            if (optional)
            {
                property.IsOptional();
            }
            else
            {
                property.IsRequired();
            }

            return(property);
        }
Example #4
0
        private static void FindNavigationProperties(this ODataModelBuilder builder, StructuralTypeConfiguration configuration,
                                                     IList <Tuple <StructuralTypeConfiguration, IList <MemberInfo>, NavigationPropertyConfiguration> > navs,
                                                     Stack <MemberInfo> path)
        {
            Contract.Assert(builder != null);
            Contract.Assert(configuration != null);
            Contract.Assert(navs != null);
            Contract.Assert(path != null);

            foreach (var property in configuration.Properties)
            {
                path.Push(property.PropertyInfo);

                NavigationPropertyConfiguration nav        = property as NavigationPropertyConfiguration;
                ComplexPropertyConfiguration    complex    = property as ComplexPropertyConfiguration;
                CollectionPropertyConfiguration collection = property as CollectionPropertyConfiguration;

                if (nav != null)
                {
                    // how about the containment?
                    IList <MemberInfo> bindingPath = path.Reverse().ToList();

                    navs.Add(
                        new Tuple <StructuralTypeConfiguration, IList <MemberInfo>, NavigationPropertyConfiguration>(configuration,
                                                                                                                     bindingPath, nav));
                }
                else if (complex != null)
                {
                    StructuralTypeConfiguration complexType = builder.GetTypeConfigurationOrNull(complex.RelatedClrType) as StructuralTypeConfiguration;
                    builder.FindAllNavigationProperties(complexType, navs, path);
                }
                else if (collection != null)
                {
                    IEdmTypeConfiguration edmType = builder.GetTypeConfigurationOrNull(collection.ElementType);
                    if (edmType != null && edmType.Kind == EdmTypeKind.Complex)
                    {
                        StructuralTypeConfiguration complexType = (StructuralTypeConfiguration)edmType;

                        builder.FindAllNavigationProperties(complexType, navs, path);
                    }
                }

                path.Pop();
            }
        }
        public virtual ComplexPropertyConfiguration AddComplexProperty(PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
            {
                throw Error.ArgumentNull("propertyInfo");
            }

            if (!propertyInfo.ReflectedType.IsAssignableFrom(ClrType))
            {
                throw Error.Argument("propertyInfo", SRResources.PropertyDoesNotBelongToType, propertyInfo.Name, ClrType.FullName);
            }

            if (propertyInfo.PropertyType == ClrType)
            {
                throw Error.Argument("propertyInfo", SRResources.RecursiveComplexTypesNotAllowed, ClrType.FullName, propertyInfo.Name);
            }

            // Remove from the ignored properties
            if (RemovedProperties.Contains(propertyInfo))
            {
                RemovedProperties.Remove(propertyInfo);
            }

            ComplexPropertyConfiguration propertyConfiguration = null;

            if (ExplicitProperties.ContainsKey(propertyInfo))
            {
                propertyConfiguration = ExplicitProperties[propertyInfo] as ComplexPropertyConfiguration;
                if (propertyConfiguration == null)
                {
                    throw Error.Argument("propertyInfo", SRResources.MustBeComplexProperty, propertyInfo.Name, ClrType.FullName);
                }
            }
            else
            {
                propertyConfiguration            = new ComplexPropertyConfiguration(propertyInfo, this);
                ExplicitProperties[propertyInfo] = propertyConfiguration;
                // Make sure the complex type is in the model.

                ModelBuilder.AddComplexType(propertyInfo.PropertyType);
            }

            return(propertyConfiguration);
        }
Example #6
0
        public virtual ComplexPropertyConfiguration AddComplexProperty(PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
            {
                throw Error.ArgumentNull("propertyInfo");
            }

            if (!propertyInfo.ReflectedType.IsAssignableFrom(ClrType))
            {
                throw Error.Argument("propertyInfo", SRResources.PropertyDoesNotBelongToType, propertyInfo.Name, ClrType.FullName);
            }

            if (propertyInfo.PropertyType == ClrType)
            {
                throw Error.Argument("propertyInfo", SRResources.RecursiveComplexTypesNotAllowed, ClrType.FullName, propertyInfo.Name);
            }

            ValidatePropertyNotAlreadyDefinedInBaseTypes(propertyInfo);
            ValidatePropertyNotAlreadyDefinedInDerivedTypes(propertyInfo);

            // Remove from the ignored properties
            if (RemovedProperties.Any(prop => prop.Name.Equals(propertyInfo.Name)))
            {
                RemovedProperties.Remove(RemovedProperties.First(prop => prop.Name.Equals(propertyInfo.Name)));
            }

            ComplexPropertyConfiguration propertyConfiguration =
                ValidatePropertyNotAlreadyDefinedOtherTypes <ComplexPropertyConfiguration>(propertyInfo,
                                                                                           SRResources.MustBeComplexProperty);

            if (propertyConfiguration == null)
            {
                propertyConfiguration            = new ComplexPropertyConfiguration(propertyInfo, this);
                ExplicitProperties[propertyInfo] = propertyConfiguration;
                // Make sure the complex type is in the model.

                ModelBuilder.AddComplexType(propertyInfo.PropertyType);
            }

            return(propertyConfiguration);
        }
Example #7
0
        private void CreateStructuralTypeBody(EdmStructuredType type, StructuralTypeConfiguration config)
        {
            foreach (PropertyConfiguration property in config.Properties)
            {
                IEdmProperty edmProperty = null;

                switch (property.Kind)
                {
                case PropertyKind.Primitive:
                    PrimitivePropertyConfiguration primitiveProperty = property as PrimitivePropertyConfiguration;
                    EdmPrimitiveTypeKind           typeKind          = GetTypeKind(primitiveProperty.PropertyInfo.PropertyType);
                    IEdmTypeReference primitiveTypeReference         = EdmCoreModel.Instance.GetPrimitive(
                        typeKind,
                        primitiveProperty.OptionalProperty);

                    // Set concurrency token if is entity type, and concurrency token is true
                    EdmConcurrencyMode concurrencyMode = EdmConcurrencyMode.None;
                    if (config.Kind == EdmTypeKind.Entity && primitiveProperty.ConcurrencyToken)
                    {
                        concurrencyMode = EdmConcurrencyMode.Fixed;
                    }
                    edmProperty = type.AddStructuralProperty(
                        primitiveProperty.Name,
                        primitiveTypeReference,
                        defaultValue: null,
                        concurrencyMode: concurrencyMode);
                    break;

                case PropertyKind.Complex:
                    ComplexPropertyConfiguration complexProperty = property as ComplexPropertyConfiguration;
                    IEdmComplexType complexType = GetEdmType(complexProperty.RelatedClrType) as IEdmComplexType;

                    edmProperty = type.AddStructuralProperty(
                        complexProperty.Name,
                        new EdmComplexTypeReference(complexType, complexProperty.OptionalProperty));
                    break;

                case PropertyKind.Collection:
                    edmProperty = CreateStructuralTypeCollectionPropertyBody(type, (CollectionPropertyConfiguration)property);
                    break;

                case PropertyKind.Enum:
                    edmProperty = CreateStructuralTypeEnumPropertyBody(type, config, (EnumPropertyConfiguration)property);
                    break;

                default:
                    break;
                }

                if (edmProperty != null)
                {
                    if (property.PropertyInfo != null)
                    {
                        _properties[property.PropertyInfo] = edmProperty;
                    }

                    if (property.IsRestricted)
                    {
                        _propertiesRestrictions[edmProperty] = new QueryableRestrictions(property);
                    }
                }
            }
        }
        public virtual ComplexPropertyConfiguration AddComplexProperty(PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
            {
                throw Error.ArgumentNull("propertyInfo");
            }

            if (!propertyInfo.ReflectedType.IsAssignableFrom(ClrType))
            {
                throw Error.Argument("propertyInfo", SRResources.PropertyDoesNotBelongToType, propertyInfo.Name, ClrType.FullName);
            }

            if (propertyInfo.PropertyType == ClrType)
            {
                throw Error.Argument("propertyInfo", SRResources.RecursiveComplexTypesNotAllowed, ClrType.FullName, propertyInfo.Name);
            }

            // Remove from the ignored properties
            if (RemovedProperties.Contains(propertyInfo))
            {
                RemovedProperties.Remove(propertyInfo);
            }

            ComplexPropertyConfiguration propertyConfiguration = null;
            if (ExplicitProperties.ContainsKey(propertyInfo))
            {
                propertyConfiguration = ExplicitProperties[propertyInfo] as ComplexPropertyConfiguration;
                if (propertyConfiguration == null)
                {
                    throw Error.Argument("propertyInfo", SRResources.MustBeComplexProperty, propertyInfo.Name, ClrType.FullName);
                }
            }
            else
            {
                propertyConfiguration = new ComplexPropertyConfiguration(propertyInfo, this);
                ExplicitProperties[propertyInfo] = propertyConfiguration;
                // Make sure the complex type is in the model.

                ModelBuilder.AddComplexType(propertyInfo.PropertyType);
            }

            return propertyConfiguration;
        }
Example #9
0
        private void CreateStructuralTypeBody(EdmStructuredType type, StructuralTypeConfiguration config)
        {
            foreach (PropertyConfiguration property in config.Properties)
            {
                IEdmProperty edmProperty = null;

                switch (property.Kind)
                {
                case PropertyKind.Primitive:
                    PrimitivePropertyConfiguration primitiveProperty = (PrimitivePropertyConfiguration)property;
                    EdmPrimitiveTypeKind           typeKind          = primitiveProperty.TargetEdmTypeKind ??
                                                                       GetTypeKind(primitiveProperty.PropertyInfo.PropertyType);
                    IEdmTypeReference primitiveTypeReference = EdmCoreModel.Instance.GetPrimitive(
                        typeKind,
                        primitiveProperty.OptionalProperty);

                    if (typeKind == EdmPrimitiveTypeKind.Decimal)
                    {
                        DecimalPropertyConfiguration decimalProperty =
                            primitiveProperty as DecimalPropertyConfiguration;
                        if (decimalProperty.Precision.HasValue || decimalProperty.Scale.HasValue)
                        {
                            primitiveTypeReference = new EdmDecimalTypeReference(
                                (IEdmPrimitiveType)primitiveTypeReference.Definition,
                                primitiveTypeReference.IsNullable,
                                decimalProperty.Precision,
                                decimalProperty.Scale.HasValue ? decimalProperty.Scale : 0);
                        }
                    }
                    else if (EdmLibHelpers.HasPrecision(typeKind))
                    {
                        PrecisionPropertyConfiguration precisionProperty =
                            primitiveProperty as PrecisionPropertyConfiguration;
                        primitiveTypeReference = AddPrecisionConfigInPrimitiveTypeReference(
                            precisionProperty,
                            primitiveTypeReference);
                    }
                    else if (EdmLibHelpers.HasLength(typeKind))
                    {
                        LengthPropertyConfiguration lengthProperty =
                            primitiveProperty as LengthPropertyConfiguration;
                        primitiveTypeReference = AddLengthConfigInPrimitiveTypeReference(
                            lengthProperty,
                            primitiveTypeReference);
                    }
                    edmProperty = type.AddStructuralProperty(
                        primitiveProperty.Name,
                        primitiveTypeReference,
                        defaultValue: null);
                    break;

                case PropertyKind.Complex:
                    ComplexPropertyConfiguration complexProperty = property as ComplexPropertyConfiguration;
                    IEdmComplexType complexType = GetEdmType(complexProperty.RelatedClrType) as IEdmComplexType;

                    edmProperty = type.AddStructuralProperty(
                        complexProperty.Name,
                        new EdmComplexTypeReference(complexType, complexProperty.OptionalProperty));
                    break;

                case PropertyKind.Collection:
                    edmProperty = CreateStructuralTypeCollectionPropertyBody(type, (CollectionPropertyConfiguration)property);
                    break;

                case PropertyKind.Enum:
                    edmProperty = CreateStructuralTypeEnumPropertyBody(type, (EnumPropertyConfiguration)property);
                    break;

                default:
                    break;
                }

                if (edmProperty != null)
                {
                    if (property.PropertyInfo != null)
                    {
                        _properties[property.PropertyInfo] = edmProperty;
                    }

                    if (property.IsRestricted)
                    {
                        _propertiesRestrictions[edmProperty] = new QueryableRestrictions(property);
                    }

                    if (property.QueryConfiguration.ModelBoundQuerySettings != null)
                    {
                        _propertiesQuerySettings.Add(edmProperty, property.QueryConfiguration.ModelBoundQuerySettings);
                    }
                }
            }
        }