private static void FindNavigationProperties(this ODataModelBuilder builder, StructuralTypeConfiguration configuration, IList <Tuple <StructuralTypeConfiguration, IList <MemberInfo>, NavigationPropertyConfiguration> > navs, Stack <MemberInfo> path, HashSet <Type> typesAlreadyProcessed) { 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 && !typesAlreadyProcessed.Contains(complex.RelatedClrType)) { StructuralTypeConfiguration complexType = builder.GetTypeConfigurationOrNull(complex.RelatedClrType) as StructuralTypeConfiguration; // Prevent infinite recursion on self-referential complex types. typesAlreadyProcessed.Add(complex.RelatedClrType); builder.FindAllNavigationPropertiesRecursive(complexType, navs, path, typesAlreadyProcessed); typesAlreadyProcessed.Remove(complex.RelatedClrType); } else if (collection != null && !typesAlreadyProcessed.Contains(collection.ElementType)) { IEdmTypeConfiguration edmType = builder.GetTypeConfigurationOrNull(collection.ElementType); if (edmType != null && edmType.Kind == EdmTypeKind.Complex) { StructuralTypeConfiguration complexType = (StructuralTypeConfiguration)edmType; // Prevent infinite recursion on self-referential complex types. typesAlreadyProcessed.Add(collection.ElementType); builder.FindAllNavigationPropertiesRecursive(complexType, navs, path, typesAlreadyProcessed); typesAlreadyProcessed.Remove(collection.ElementType); } } path.Pop(); } }
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); }
public virtual ComplexPropertyConfiguration AddComplexProperty(PropertyInfo propertyInfo) { if (propertyInfo == null) { throw Error.ArgumentNull("propertyInfo"); } if (!propertyInfo.DeclaringType.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.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); }
public virtual ComplexPropertyConfiguration AddComplexProperty(PropertyInfo propertyInfo) { if (propertyInfo == null) { throw Error.ArgumentNull("propertyInfo"); } if (!TypeHelper.GetReflectedType(propertyInfo).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); }
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); } } } }
public virtual ComplexPropertyConfiguration AddComplexProperty(PropertyInfo propertyInfo) { if (propertyInfo == null) { throw Error.ArgumentNull("propertyInfo"); } if (!propertyInfo.DeclaringType.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.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; }
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); } } } }