/// <summary> /// Factory method for creating a string TypeUsage object with the specified facets /// </summary> /// <param name="primitiveType">A PrimitiveType for which to construct the TypeUsage</param> /// <param name="isUnicode">Whether the string type is unicode or not</param> /// <param name="isFixedLength">Whether the string type is fixed length or not</param> /// <param name="maxLength">The max length of the string type</param> /// <returns>A TypeUsage object describing a string type with the given facet values</returns> public static TypeUsage CreateStringTypeUsage(PrimitiveType primitiveType, bool isUnicode, bool isFixedLength, int maxLength) { EntityUtil.CheckArgumentNull <PrimitiveType>(primitiveType, "primitiveType"); if (primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.String) { throw EntityUtil.NotStringTypeForTypeUsage(); } ValidateMaxLength(maxLength); TypeUsage typeUsage = TypeUsage.Create(primitiveType, new FacetValues { MaxLength = maxLength, Unicode = isUnicode, FixedLength = isFixedLength }); return(typeUsage); }
/// <summary> /// Validates whether cspace and sspace types are compatible. /// </summary> /// <param name="cspaceType">Type in C-Space. Must be a primitive or enumeration type.</param> /// <param name="storeType">C-Space equivalent of S-space Type. Must be a primitive type.</param> /// <returns> /// <c>true</c> if the types are compatible. <c>false</c> otherwise. /// </returns> /// <remarks> /// This methods validate whether cspace and sspace types are compatible. The types are /// compatible if: /// both are primitive and the cspace type is a subtype of sspace type /// or /// cspace type is an enumeration type whose underlying type is a subtype of sspace type. /// </remarks> private static bool ValidateScalarTypesAreCompatible(TypeUsage cspaceType, TypeUsage storeType) { Debug.Assert(cspaceType != null, "cspaceType != null"); Debug.Assert(storeType != null, "storeType != null"); Debug.Assert(cspaceType.EdmType.DataSpace == DataSpace.CSpace, "cspace property must have a cspace type"); Debug.Assert(storeType.EdmType.DataSpace == DataSpace.CSpace, "storeType type usage must have a sspace type"); Debug.Assert( Helper.IsScalarType(cspaceType.EdmType), "cspace property must be of a primitive or enumeration type"); Debug.Assert(Helper.IsPrimitiveType(storeType.EdmType), "storeType property must be a primitive type"); if (Helper.IsEnumType(cspaceType.EdmType)) { // For enum cspace type check whether its underlying type is a subtype of the store type. Note that // TypeSemantics.IsSubTypeOf uses only TypeUsage.EdmType for primitive types so there is no need to copy facets // from the enum type property to the underlying type TypeUsage created here since they wouldn't be used anyways. return(TypeSemantics.IsSubTypeOf(TypeUsage.Create(Helper.GetUnderlyingEdmTypeForEnumType(cspaceType.EdmType)), storeType)); } return(TypeSemantics.IsSubTypeOf(cspaceType, storeType)); }
/// <summary> /// Resolves enum type property. /// </summary> /// <param name="declaringType">The type to add the declared property to.</param> /// <param name="clrProperty">Property to resolve.</param> private void ResolveEnumTypeProperty(StructuralType declaringType, PropertyInfo clrProperty) { Debug.Assert(declaringType != null, "type != null"); Debug.Assert(clrProperty != null, "clrProperty != null"); Debug.Assert( (Nullable.GetUnderlyingType(clrProperty.PropertyType) ?? clrProperty.PropertyType).IsEnum, "This method should be called for enums only"); EdmType propertyType; if (!TryGetLoadedType(clrProperty.PropertyType, out propertyType) || !Helper.IsEnumType(propertyType)) { SessionData.EdmItemErrors.Add( new EdmItemError( System.Data.Entity.Strings.Validator_OSpace_ScalarPropertyNotPrimitive( clrProperty.Name, clrProperty.DeclaringType.FullName, clrProperty.PropertyType.FullName), null)); } else { var edmScalarPropertyAttribute = (EdmScalarPropertyAttribute)clrProperty.GetCustomAttributes(typeof(EdmScalarPropertyAttribute), false).Single(); EdmProperty enumProperty = new EdmProperty( clrProperty.Name, TypeUsage.Create(propertyType, new FacetValues() { Nullable = edmScalarPropertyAttribute.IsNullable }), clrProperty, declaringType.ClrType.TypeHandle); declaringType.AddMember(enumProperty); if (declaringType.BuiltInTypeKind == BuiltInTypeKind.EntityType && edmScalarPropertyAttribute.EntityKeyProperty) { ((EntityType)declaringType).AddKeyMember(enumProperty); } } }
private void CreateAndAddComplexType(Type type, StructuralType ospaceType, EdmProperty cspaceProperty, PropertyInfo clrProperty) { EdmType propertyType; if (SessionData.CspaceToOspace.TryGetValue((StructuralType)cspaceProperty.TypeUsage.EdmType, out propertyType)) { Debug.Assert(propertyType is StructuralType, "Structural type expected."); EdmProperty property = new EdmProperty(cspaceProperty.Name, TypeUsage.Create(propertyType, new FacetValues { Nullable = false }), clrProperty, type.TypeHandle); ospaceType.AddMember(property); } else { string message = SessionData.LoadMessageLogger.CreateErrorMessageWithTypeSpecificLoadLogs( Strings.Validator_OSpace_Convention_MissingOSpaceType(cspaceProperty.TypeUsage.EdmType.FullName), cspaceProperty.TypeUsage.EdmType); SessionData.EdmItemErrors.Add(new EdmItemError(message, ospaceType)); } }
private void ResolveComplexTypeProperty(StructuralType type, PropertyInfo clrProperty) { // Load the property type and create a new property object EdmType propertyType; // If the type could not be loaded it's definitely not a complex type, so that's an error // If it could be loaded but is not a complex type that's an error as well if (!TryGetLoadedType(clrProperty.PropertyType, out propertyType) || propertyType.BuiltInTypeKind != BuiltInTypeKind.ComplexType) { // This property does not need to be validated further, just add to the errors collection and continue with the next property // This failure will cause an exception to be thrown later during validation of all of the types SessionData.EdmItemErrors.Add(new EdmItemError(System.Data.Entity.Strings.Validator_OSpace_ComplexPropertyNotComplex(clrProperty.Name, clrProperty.DeclaringType.FullName, clrProperty.PropertyType.FullName), null)); } else { EdmProperty newProperty = new EdmProperty(clrProperty.Name, TypeUsage.Create(propertyType, new FacetValues { Nullable = false }), clrProperty, type.ClrType.TypeHandle); type.AddMember(newProperty); } }
/// <summary> /// The constructor for constructing a CollectionType object with the element type it contains /// </summary> /// <param name="elementType">The element type that this collection type contains</param> /// <exception cref="System.ArgumentNullException">Thrown if the argument elementType is null</exception> internal CollectionType(EdmType elementType) : this(TypeUsage.Create(elementType)) { this.DataSpace = elementType.DataSpace; }
internal void ResolveNavigationProperty(StructuralType declaringType, PropertyInfo propertyInfo) { Debug.Assert(propertyInfo.IsDefined(typeof(EdmRelationshipNavigationPropertyAttribute), false), "The property must have navigation property defined"); // EdmScalarPropertyAttribute, EdmComplexPropertyAttribute and EdmRelationshipNavigationPropertyAttribute // are all EdmPropertyAttributes that we need to process. If the current property is not an EdmPropertyAttribute // we will just ignore it and skip to the next property. object[] relationshipPropertyAttributes = propertyInfo.GetCustomAttributes(typeof(EdmRelationshipNavigationPropertyAttribute), false); Debug.Assert(relationshipPropertyAttributes.Length == 1, "There should be exactly one property for every navigation property"); // The only valid return types from navigation properties are: // (1) EntityType // (2) CollectionType containing valid EntityType // If TryGetLoadedType returned false, it could mean that we couldn't validate any part of the type, or it could mean that it's a generic // where the main generic type was validated, but the generic type parameter was not. We can't tell the difference, so just fail // with the same error message in both cases. The user will have to figure out which part of the type is wrong. // We can't just rely on checking for a generic because it can lead to a scenario where we report that the type parameter is invalid // when really it's the main generic type. That is more confusing than reporting the full name and letting the user determine the problem. EdmType propertyType; if (!TryGetLoadedType(propertyInfo.PropertyType, out propertyType) || !(propertyType.BuiltInTypeKind == BuiltInTypeKind.EntityType || propertyType.BuiltInTypeKind == BuiltInTypeKind.CollectionType)) { // Once an error is detected the property does not need to be validated further, just add to the errors // collection and continue with the next property. The failure will cause an exception to be thrown later during validation of all of the types. SessionData.EdmItemErrors.Add(new EdmItemError(System.Data.Entity.Strings.Validator_OSpace_InvalidNavPropReturnType(propertyInfo.Name, propertyInfo.DeclaringType.FullName, propertyInfo.PropertyType.FullName), null)); return; } // else we have a valid EntityType or CollectionType that contains EntityType. ResolveNonSchemaType enforces that a collection type // must contain an EntityType, and if it doesn't, propertyType will be null here. If propertyType is EntityType or CollectionType we know it is valid // Expecting EdmRelationshipNavigationPropertyAttribute to have AllowMultiple=False, so only look at first element in the attribute array EdmRelationshipNavigationPropertyAttribute attribute = (EdmRelationshipNavigationPropertyAttribute)relationshipPropertyAttributes[0]; EdmMember member = null; EdmType type; if (SessionData.TypesInLoading.TryGetValue(attribute.RelationshipNamespaceName + "." + attribute.RelationshipName, out type) && Helper.IsAssociationType(type)) { AssociationType relationshipType = (AssociationType)type; if (relationshipType != null) { // The return value of this property has been verified, so create the property now NavigationProperty navigationProperty = new NavigationProperty(propertyInfo.Name, TypeUsage.Create(propertyType), propertyInfo); navigationProperty.RelationshipType = relationshipType; member = navigationProperty; if (relationshipType.Members[0].Name == attribute.TargetRoleName) { navigationProperty.ToEndMember = (RelationshipEndMember)relationshipType.Members[0]; navigationProperty.FromEndMember = (RelationshipEndMember)relationshipType.Members[1]; } else if (relationshipType.Members[1].Name == attribute.TargetRoleName) { navigationProperty.ToEndMember = (RelationshipEndMember)relationshipType.Members[1]; navigationProperty.FromEndMember = (RelationshipEndMember)relationshipType.Members[0]; } else { SessionData.EdmItemErrors.Add(new EdmItemError(System.Data.Entity.Strings.TargetRoleNameInNavigationPropertyNotValid( propertyInfo.Name, propertyInfo.DeclaringType.FullName, attribute.TargetRoleName, attribute.RelationshipName), navigationProperty)); member = null; } if (member != null && ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType != declaringType.ClrType) { SessionData.EdmItemErrors.Add(new EdmItemError(System.Data.Entity.Strings.NavigationPropertyRelationshipEndTypeMismatch( declaringType.FullName, navigationProperty.Name, relationshipType.FullName, navigationProperty.FromEndMember.Name, ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType), navigationProperty)); member = null; } } } else { SessionData.EdmItemErrors.Add(new EdmItemError(System.Data.Entity.Strings.RelationshipNameInNavigationPropertyNotValid( propertyInfo.Name, propertyInfo.DeclaringType.FullName, attribute.RelationshipName), declaringType)); } if (member != null) { declaringType.AddMember(member); } }
internal TypeUsage ShallowCopy(FacetValues facetValues) { return(TypeUsage.Create(_edmType, OverrideFacetValues(Facets, facetValues))); }
/// <summary> /// Returns a Model type usage for a provider type /// </summary> /// <returns>model (CSpace) type usage</returns> internal TypeUsage GetModelTypeUsage() { if (_modelTypeUsage == null) { EdmType edmType = this.EdmType; // If the edm type is already a cspace type, return the same type if (edmType.DataSpace == DataSpace.CSpace || edmType.DataSpace == DataSpace.OSpace) { return(this); } TypeUsage result; if (Helper.IsRowType(edmType)) { RowType sspaceRowType = (RowType)edmType; EdmProperty[] properties = new EdmProperty[sspaceRowType.Properties.Count]; for (int i = 0; i < properties.Length; i++) { EdmProperty sspaceProperty = sspaceRowType.Properties[i]; TypeUsage newTypeUsage = sspaceProperty.TypeUsage.GetModelTypeUsage(); properties[i] = new EdmProperty(sspaceProperty.Name, newTypeUsage); } RowType edmRowType = new RowType(properties, sspaceRowType.InitializerMetadata); result = TypeUsage.Create(edmRowType, this.Facets); } else if (Helper.IsCollectionType(edmType)) { CollectionType sspaceCollectionType = ((CollectionType)edmType); TypeUsage newTypeUsage = sspaceCollectionType.TypeUsage.GetModelTypeUsage(); result = TypeUsage.Create(new CollectionType(newTypeUsage), this.Facets); } else if (Helper.IsRefType(edmType)) { System.Diagnostics.Debug.Assert(((RefType)edmType).ElementType.DataSpace == DataSpace.CSpace); result = this; } else if (Helper.IsPrimitiveType(edmType)) { result = ((PrimitiveType)edmType).ProviderManifest.GetEdmType(this); if (result == null) { throw EntityUtil.ProviderIncompatible(System.Data.Entity.Strings.Mapping_ProviderReturnsNullType(this.ToString())); } if (!TypeSemantics.IsNullable(this)) { result = TypeUsage.Create(result.EdmType, OverrideFacetValues(result.Facets, new FacetValues { Nullable = false })); } } else if (Helper.IsEntityTypeBase(edmType) || Helper.IsComplexType(edmType)) { result = this; } else { System.Diagnostics.Debug.Assert(false, "Unexpected type found in entity data reader"); return(null); } System.Threading.Interlocked.CompareExchange(ref _modelTypeUsage, result, null); } return(_modelTypeUsage); }
/// <summary> /// determines if two types are equivalent or if fromType is promotable to toType /// </summary> /// <param name="fromType"></param> /// <param name="toType"></param> /// <returns>true if fromType equivalent or promotable to toType, false otherwise</returns> internal static bool IsStructurallyEqualOrPromotableTo(EdmType fromType, EdmType toType) { return(IsStructurallyEqualOrPromotableTo(TypeUsage.Create(fromType), TypeUsage.Create(toType))); }
/// <summary> /// determines if fromEdmType can be cast to toEdmType. this operation is valid only /// if fromtype and totype are polimorphic types. /// </summary> /// <param name="fromType"></param> /// <param name="toType"></param> /// <returns></returns> internal static bool IsValidPolymorphicCast(EdmType fromEdmType, EdmType toEdmType) { return(IsValidPolymorphicCast(TypeUsage.Create(fromEdmType), TypeUsage.Create(toEdmType))); }
/// <summary> /// Static Constructor which initializes all the built in types and primitive types /// </summary> static MetadataItem() { //////////////////////////////////////////////////////////////////////////////////////////////// // Bootstrapping the builtin types //////////////////////////////////////////////////////////////////////////////////////////////// _builtInTypes[(int)BuiltInTypeKind.AssociationEndMember] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.AssociationSet] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.AssociationSetEnd] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.AssociationType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.AssociationType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.CollectionKind] = new EnumType(); _builtInTypes[(int)BuiltInTypeKind.CollectionType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.ComplexType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.Documentation] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.OperationAction] = new EnumType(); _builtInTypes[(int)BuiltInTypeKind.EdmType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.EntityContainer] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.EntitySet] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.EntityType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.EntitySetBase] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.EntityTypeBase] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.EnumType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.EnumMember] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.Facet] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.EdmFunction] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.FunctionParameter] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.GlobalItem] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.MetadataProperty] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.NavigationProperty] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.MetadataItem] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.EdmMember] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.ParameterMode] = new EnumType(); _builtInTypes[(int)BuiltInTypeKind.PrimitiveType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.PrimitiveTypeKind] = new EnumType(); _builtInTypes[(int)BuiltInTypeKind.EdmProperty] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.ProviderManifest] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.ReferentialConstraint] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.RefType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.RelationshipEndMember] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.RelationshipMultiplicity] = new EnumType(); _builtInTypes[(int)BuiltInTypeKind.RelationshipSet] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.RelationshipType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.RowType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.SimpleType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.StructuralType] = new ComplexType(); _builtInTypes[(int)BuiltInTypeKind.TypeUsage] = new ComplexType(); //////////////////////////////////////////////////////////////////////////////////////////////// // Initialize item attributes for all the built-in complex types //////////////////////////////////////////////////////////////////////////////////////////////// InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem), EdmConstants.ItemType, false /*isAbstract*/, null); // populate the attributes for item attributes InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataProperty), EdmConstants.ItemAttribute, true /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.GlobalItem), EdmConstants.GlobalItem, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.TypeUsage), EdmConstants.TypeUsage, false, /*isAbstract*/ (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); //populate the attributes for the edm type InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.EdmType), EdmConstants.EdmType, true, /*isAbstract*/ (ComplexType)GetBuiltInType(BuiltInTypeKind.GlobalItem)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.SimpleType), EdmConstants.SimpleType, true /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EdmType)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.EnumType), EdmConstants.EnumerationType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.SimpleType)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.PrimitiveType), EdmConstants.PrimitiveType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.SimpleType)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.CollectionType), EdmConstants.CollectionType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EdmType)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.RefType), EdmConstants.RefType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EdmType)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.EdmMember), EdmConstants.Member, true /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.EdmProperty), EdmConstants.Property, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EdmMember)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.NavigationProperty), EdmConstants.NavigationProperty, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EdmMember)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.ProviderManifest), EdmConstants.ProviderManifest, true /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.RelationshipEndMember), EdmConstants.RelationshipEnd, true /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EdmMember)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.AssociationEndMember), EdmConstants.AssociationEnd, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.RelationshipEndMember)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.EnumMember), EdmConstants.EnumerationMember, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.ReferentialConstraint), EdmConstants.ReferentialConstraint, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); // Structural Type hierarchy InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.StructuralType), EdmConstants.StructuralType, true /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EdmType)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.RowType), EdmConstants.RowType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.StructuralType)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.ComplexType), EdmConstants.ComplexType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.StructuralType)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.EntityTypeBase), EdmConstants.ElementType, true /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.StructuralType)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.EntityType), EdmConstants.EntityType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EntityTypeBase)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.RelationshipType), EdmConstants.RelationshipType, true /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EntityTypeBase)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.AssociationType), EdmConstants.AssociationType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.RelationshipType)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.Facet), EdmConstants.Facet, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.EntityContainer), EdmConstants.EntityContainerType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.GlobalItem)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.EntitySetBase), EdmConstants.BaseEntitySetType, true /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.EntitySet), EdmConstants.EntitySetType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EntitySetBase)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.RelationshipSet), EdmConstants.RelationshipSet, true /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EntitySetBase)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.AssociationSet), EdmConstants.AssociationSetType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.RelationshipSet)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.AssociationSetEnd), EdmConstants.AssociationSetEndType, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.FunctionParameter), EdmConstants.FunctionParameter, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.EdmFunction), EdmConstants.Function, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.EdmType)); InitializeBuiltInTypes((ComplexType)GetBuiltInType(BuiltInTypeKind.Documentation), EdmConstants.Documentation, false /*isAbstract*/, (ComplexType)GetBuiltInType(BuiltInTypeKind.MetadataItem)); //////////////////////////////////////////////////////////////////////////////////////////////// // Initialize item attributes for all the built-in enum types //////////////////////////////////////////////////////////////////////////////////////////////// InitializeEnumType(BuiltInTypeKind.OperationAction, EdmConstants.DeleteAction, new string[] { EdmConstants.None, EdmConstants.Cascade, EdmConstants.Restrict }); InitializeEnumType(BuiltInTypeKind.RelationshipMultiplicity, EdmConstants.RelationshipMultiplicity, new string[] { EdmConstants.One, EdmConstants.ZeroToOne, EdmConstants.Many }); InitializeEnumType(BuiltInTypeKind.ParameterMode, EdmConstants.ParameterMode, new string[] { EdmConstants.In, EdmConstants.Out, EdmConstants.InOut }); InitializeEnumType(BuiltInTypeKind.CollectionKind, EdmConstants.CollectionKind, new string[] { EdmConstants.NoneCollectionKind, EdmConstants.ListCollectionKind, EdmConstants.BagCollectionKind }); InitializeEnumType(BuiltInTypeKind.PrimitiveTypeKind, EdmConstants.PrimitiveTypeKind, Enum.GetNames(typeof(PrimitiveTypeKind))); //////////////////////////////////////////////////////////////////////////////////////////////// // Bootstrapping the general facet descriptions //////////////////////////////////////////////////////////////////////////////////////////////// // Other type non-specific facets FacetDescription[] generalFacetDescriptions = new FacetDescription[2]; _nullableFacetDescription = new FacetDescription(DbProviderManifest.NullableFacetName, EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean), null, null, true); generalFacetDescriptions[0] = (_nullableFacetDescription); _defaultValueFacetDescription = new FacetDescription(DbProviderManifest.DefaultValueFacetName, MetadataItem.GetBuiltInType(BuiltInTypeKind.EdmType), null, null, null); generalFacetDescriptions[1] = (_defaultValueFacetDescription); _generalFacetDescriptions = Array.AsReadOnly(generalFacetDescriptions); _collectionKindFacetDescription = new FacetDescription(XmlConstants.CollectionKind, MetadataItem.GetBuiltInType(BuiltInTypeKind.EnumType), null, null, null); //////////////////////////////////////////////////////////////////////////////////////////////// // Add properties for the built-in complex types //////////////////////////////////////////////////////////////////////////////////////////////// TypeUsage stringTypeUsage = TypeUsage.Create(EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.String)); TypeUsage booleanTypeUsage = TypeUsage.Create(EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean)); TypeUsage edmTypeUsage = TypeUsage.Create(MetadataItem.GetBuiltInType(BuiltInTypeKind.EdmType)); TypeUsage typeUsageTypeUsage = TypeUsage.Create(MetadataItem.GetBuiltInType(BuiltInTypeKind.TypeUsage)); TypeUsage complexTypeUsage = TypeUsage.Create(MetadataItem.GetBuiltInType(BuiltInTypeKind.ComplexType)); // populate the attributes for item attributes AddBuiltInTypeProperties(BuiltInTypeKind.MetadataProperty, new EdmProperty[] { new EdmProperty(EdmConstants.Name, stringTypeUsage), new EdmProperty(EdmConstants.TypeUsage, typeUsageTypeUsage), new EdmProperty(EdmConstants.Value, complexTypeUsage) }); AddBuiltInTypeProperties(BuiltInTypeKind.MetadataItem, new EdmProperty[] { new EdmProperty(EdmConstants.ItemAttributes, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.MetadataProperty).GetCollectionType())), new EdmProperty(EdmConstants.Documentation, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.Documentation))) }); AddBuiltInTypeProperties(BuiltInTypeKind.TypeUsage, new EdmProperty[] { new EdmProperty(EdmConstants.EdmType, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EdmType))), new EdmProperty(EdmConstants.Facets, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.Facet))) }); //populate the attributes for the edm type AddBuiltInTypeProperties(BuiltInTypeKind.EdmType, new EdmProperty[] { new EdmProperty(EdmConstants.Name, stringTypeUsage), new EdmProperty(EdmConstants.Namespace, stringTypeUsage), new EdmProperty(EdmConstants.Abstract, booleanTypeUsage), new EdmProperty(EdmConstants.Sealed, booleanTypeUsage), new EdmProperty(EdmConstants.BaseType, complexTypeUsage) }); AddBuiltInTypeProperties(BuiltInTypeKind.EnumType, new EdmProperty[] { new EdmProperty(EdmConstants.EnumMembers, stringTypeUsage) }); AddBuiltInTypeProperties(BuiltInTypeKind.CollectionType, new EdmProperty[] { new EdmProperty(EdmConstants.TypeUsage, typeUsageTypeUsage) }); AddBuiltInTypeProperties(BuiltInTypeKind.RefType, new EdmProperty[] { new EdmProperty(EdmConstants.EntityType, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EntityType))) }); AddBuiltInTypeProperties(BuiltInTypeKind.EdmMember, new EdmProperty[] { new EdmProperty(EdmConstants.Name, stringTypeUsage), new EdmProperty(EdmConstants.TypeUsage, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.TypeUsage))) }); AddBuiltInTypeProperties(BuiltInTypeKind.EdmProperty, new EdmProperty[] { new EdmProperty(EdmConstants.Nullable, stringTypeUsage), new EdmProperty(EdmConstants.DefaultValue, complexTypeUsage) }); AddBuiltInTypeProperties(BuiltInTypeKind.NavigationProperty, new EdmProperty[] { new EdmProperty(EdmConstants.RelationshipTypeName, stringTypeUsage), new EdmProperty(EdmConstants.ToEndMemberName, stringTypeUsage) }); AddBuiltInTypeProperties(BuiltInTypeKind.RelationshipEndMember, new EdmProperty[] { new EdmProperty(EdmConstants.OperationBehaviors, complexTypeUsage), new EdmProperty(EdmConstants.RelationshipMultiplicity, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EnumType))) }); AddBuiltInTypeProperties(BuiltInTypeKind.EnumMember, new EdmProperty[] { new EdmProperty(EdmConstants.Name, stringTypeUsage) }); AddBuiltInTypeProperties(BuiltInTypeKind.ReferentialConstraint, new EdmProperty[] { new EdmProperty(EdmConstants.ToRole, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.RelationshipEndMember))), new EdmProperty(EdmConstants.FromRole, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.RelationshipEndMember))), new EdmProperty(EdmConstants.ToProperties, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EdmProperty).GetCollectionType())), new EdmProperty(EdmConstants.FromProperties, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EdmProperty).GetCollectionType())) }); // Structural Type hierarchy AddBuiltInTypeProperties(BuiltInTypeKind.StructuralType, new EdmProperty[] { new EdmProperty(EdmConstants.Members, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EdmMember))) }); AddBuiltInTypeProperties(BuiltInTypeKind.EntityTypeBase, new EdmProperty[] { new EdmProperty(EdmConstants.KeyMembers, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EdmMember))) }); AddBuiltInTypeProperties(BuiltInTypeKind.Facet, new EdmProperty[] { new EdmProperty(EdmConstants.Name, stringTypeUsage), new EdmProperty(EdmConstants.EdmType, edmTypeUsage), new EdmProperty(EdmConstants.Value, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EdmType))) }); AddBuiltInTypeProperties(BuiltInTypeKind.EntityContainer, new EdmProperty[] { new EdmProperty(EdmConstants.Name, stringTypeUsage), new EdmProperty(EdmConstants.EntitySets, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EntitySet))) }); AddBuiltInTypeProperties(BuiltInTypeKind.EntitySetBase, new EdmProperty[] { new EdmProperty(EdmConstants.Name, stringTypeUsage), new EdmProperty(EdmConstants.EntityType, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EntityType))), new EdmProperty(EdmConstants.Schema, stringTypeUsage), new EdmProperty(EdmConstants.Table, stringTypeUsage) }); AddBuiltInTypeProperties(BuiltInTypeKind.AssociationSet, new EdmProperty[] { new EdmProperty(EdmConstants.AssociationSetEnds, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.AssociationSetEnd).GetCollectionType())) }); AddBuiltInTypeProperties(BuiltInTypeKind.AssociationSetEnd, new EdmProperty[] { new EdmProperty(EdmConstants.Role, stringTypeUsage), new EdmProperty(EdmConstants.EntitySetType, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EntitySet))) }); AddBuiltInTypeProperties(BuiltInTypeKind.FunctionParameter, new EdmProperty[] { new EdmProperty(EdmConstants.Name, stringTypeUsage), new EdmProperty(EdmConstants.Mode, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.EnumType))), new EdmProperty(EdmConstants.TypeUsage, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.TypeUsage))) }); AddBuiltInTypeProperties(BuiltInTypeKind.EdmFunction, new EdmProperty[] { new EdmProperty(EdmConstants.Name, stringTypeUsage), new EdmProperty(EdmConstants.Namespace, stringTypeUsage), new EdmProperty(EdmConstants.ReturnParameter, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.FunctionParameter))), new EdmProperty(EdmConstants.Parameters, TypeUsage.Create(GetBuiltInType(BuiltInTypeKind.FunctionParameter).GetCollectionType())) }); AddBuiltInTypeProperties(BuiltInTypeKind.Documentation, new EdmProperty[] { new EdmProperty(EdmConstants.Summary, stringTypeUsage), new EdmProperty(EdmConstants.LongDescription, stringTypeUsage) }); // Set all types to be readonly, used SetReadOnly to skip validation method to for (int i = 0; i < _builtInTypes.Length; i++) { _builtInTypes[i].SetReadOnly(); } }
private FunctionParameter CreateAggregateParameter(PrimitiveTypeKind collectionParameterTypeElementTypeKind) { return(new FunctionParameter("collection", TypeUsage.Create(this.primitiveTypes[(int)collectionParameterTypeElementTypeKind].EdmType.GetCollectionType()), ParameterMode.In)); }
private void CreateAndAddNavigationProperty(StructuralType cspaceType, StructuralType ospaceType, NavigationProperty cspaceProperty, PropertyInfo clrProperty) { EdmType ospaceRelationship; if (SessionData.CspaceToOspace.TryGetValue(cspaceProperty.RelationshipType, out ospaceRelationship)) { Debug.Assert(ospaceRelationship is StructuralType, "Structural type expected."); bool foundTarget = false; EdmType targetType = null; if (Helper.IsCollectionType(cspaceProperty.TypeUsage.EdmType)) { EdmType findType; foundTarget = SessionData.CspaceToOspace.TryGetValue((StructuralType)((CollectionType)cspaceProperty.TypeUsage.EdmType).TypeUsage.EdmType, out findType); if (foundTarget) { Debug.Assert(findType is StructuralType, "Structural type expected."); targetType = findType.GetCollectionType(); } } else { EdmType findType; foundTarget = SessionData.CspaceToOspace.TryGetValue((StructuralType)cspaceProperty.TypeUsage.EdmType, out findType); if (foundTarget) { Debug.Assert(findType is StructuralType, "Structural type expected."); targetType = findType; } } Debug.Assert(foundTarget, "Since the relationship will only be created if it can find the types for both ends, we will never fail to find one of the ends"); NavigationProperty navigationProperty = new NavigationProperty(cspaceProperty.Name, TypeUsage.Create(targetType), clrProperty); navigationProperty.RelationshipType = (RelationshipType)ospaceRelationship; // we can use First because o-space relationships are created directly from // c-space relationship navigationProperty.ToEndMember = (RelationshipEndMember)((RelationshipType)ospaceRelationship).Members.First(e => e.Name == cspaceProperty.ToEndMember.Name); navigationProperty.FromEndMember = (RelationshipEndMember)((RelationshipType)ospaceRelationship).Members.First(e => e.Name == cspaceProperty.FromEndMember.Name); ospaceType.AddMember(navigationProperty); } else { EntityTypeBase missingType = cspaceProperty.RelationshipType.RelationshipEndMembers.Select(e => ((RefType)e.TypeUsage.EdmType).ElementType).First(e => e != cspaceType); string message = SessionData.LoadMessageLogger.CreateErrorMessageWithTypeSpecificLoadLogs( Strings.Validator_OSpace_Convention_RelationshipNotLoaded(cspaceProperty.RelationshipType.FullName, missingType.FullName), missingType); SessionData.EdmItemErrors.Add(new EdmItemError(message, ospaceType)); } }