private void ValidateOnlyBaseEntitySetTypeDefinesConcurrency() { // collect all the base entitySet types Dictionary <SchemaEntityType, EntityContainerEntitySet> baseEntitySetTypes = new Dictionary <SchemaEntityType, EntityContainerEntitySet>(); foreach (SchemaElement element in Members) { EntityContainerEntitySet entitySet = element as EntityContainerEntitySet; if (entitySet != null && !baseEntitySetTypes.ContainsKey(entitySet.EntityType)) { baseEntitySetTypes.Add(entitySet.EntityType, entitySet); } } // look through each type in this schema and see if it is derived from a base // type if it is then see if it has some "new" Concurrency fields foreach (SchemaType type in Schema.SchemaTypes) { SchemaEntityType itemType = type as SchemaEntityType; if (itemType != null) { EntityContainerEntitySet set; if (TypeIsSubTypeOf(itemType, baseEntitySetTypes, out set) && TypeDefinesNewConcurrencyProperties(itemType)) { AddError(ErrorCode.ConcurrencyRedefinedOnSubTypeOfEntitySetType, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.ConcurrencyRedefinedOnSubTypeOfEntitySetType(itemType.FQName, set.EntityType.FQName, set.FQName)); } } } }
/// <summary> /// Handler for the EntityType element /// </summary> /// <param name="reader">xml reader currently positioned at EntityType element</param> private void HandleEntityTypeElement(XmlReader reader) { Debug.Assert(reader != null); SchemaEntityType itemType = new SchemaEntityType(this); itemType.Parse(reader); TryAddType(itemType, true /*doNotAddErrorForEmptyName*/); }
private static bool TypeDefinesNewConcurrencyProperties(SchemaEntityType itemType) { foreach (StructuredProperty property in itemType.Properties) { if (property.Type is ScalarType && MetadataHelper.GetConcurrencyMode(property.TypeUsage) != ConcurrencyMode.None) { return(true); } } return(false); }
/// <summary> /// Since this method can be used in different context, this method does not add any errors /// Please make sure that the caller of this methods handles the error case and add errors /// appropriately /// </summary> /// <param name="entityType"></param> /// <returns></returns> internal bool ResolveNames(SchemaEntityType entityType) { if (string.IsNullOrEmpty(this.Name)) { // Don't flag this error. This must already must have flaged as error, while handling name attribute return true; } // Make sure there is a property by this name _property = entityType.FindProperty(this.Name); return (_property != null); }
/// <summary> /// Since this method can be used in different context, this method does not add any errors /// Please make sure that the caller of this methods handles the error case and add errors /// appropriately /// </summary> /// <param name="entityType"></param> /// <returns></returns> internal bool ResolveNames(SchemaEntityType entityType) { if (string.IsNullOrEmpty(this.Name)) { // Don't flag this error. This must already must have flaged as error, while handling name attribute return(true); } // Make sure there is a property by this name _property = entityType.FindProperty(this.Name); return(_property != null); }
/// <summary> /// Used during the resolve phase to resolve the type name to the object that represents that type /// </summary> internal override void ResolveTopLevelNames() { base.ResolveTopLevelNames(); if (_entityType == null) { SchemaType type = null; if (!Schema.ResolveTypeName(this, _unresolvedEntityTypeName, out type)) { return; } _entityType = type as SchemaEntityType; if (_entityType == null) { AddError(ErrorCode.InvalidPropertyType, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidEntitySetType(_unresolvedEntityTypeName)); return; } } }
private static bool TypeIsSubTypeOf(SchemaEntityType itemType, Dictionary <SchemaEntityType, EntityContainerEntitySet> baseEntitySetTypes, out EntityContainerEntitySet set) { if (itemType.IsTypeHierarchyRoot) { // can't be a sub type if we are a base type set = null; return(false); } // walk up the hierarchy looking for a base that is the base type of an entityset for (SchemaEntityType baseType = itemType.BaseType as SchemaEntityType; baseType != null; baseType = baseType.BaseType as SchemaEntityType) { if (baseEntitySetTypes.ContainsKey(baseType)) { set = baseEntitySetTypes[baseType]; return(true); } } set = null; return(false); }
/// <summary> /// /// </summary> /// <param name="parent"></param> public NavigationProperty(SchemaEntityType parent) : base(parent) { }
/// <summary> /// Used during the resolve phase to resolve the type name to the object that represents that type /// </summary> internal override void ResolveTopLevelNames() { base.ResolveTopLevelNames(); if ( _entityType == null ) { SchemaType type = null; if ( ! Schema.ResolveTypeName( this, _unresolvedEntityTypeName, out type) ) { return; } _entityType = type as SchemaEntityType; if ( _entityType == null ) { AddError( ErrorCode.InvalidPropertyType, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidEntitySetType(_unresolvedEntityTypeName ) ); return; } } }
/// <summary> /// Constructs an EntityContainerAssociationSetEnd /// </summary> /// <param name="parentElement">Reference to the schema element.</param> public EntityKeyElement(SchemaEntityType parentElement) : base(parentElement) { }
/// <summary> /// Resolves the given property names to the property in the item /// Also checks whether the properties form the key for the given type and whether all the properties are nullable or not /// </summary> /// <param name="roleElement"></param> /// <param name="itemType"></param> /// <param name="isKeyProperty"></param> /// <param name="areAllPropertiesNullable"></param> /// <param name="isSubsetOfKeyProperties"></param> private static void IsKeyProperty(ReferentialConstraintRoleElement roleElement, SchemaEntityType itemType, out bool isKeyProperty, out bool areAllPropertiesNullable, out bool isAnyPropertyNullable, out bool isSubsetOfKeyProperties) { isKeyProperty = true; areAllPropertiesNullable = true; isAnyPropertyNullable = false; isSubsetOfKeyProperties = true; if (itemType.KeyProperties.Count != roleElement.RoleProperties.Count) { isKeyProperty = false; } // Checking that ToProperties must be the key properties in the entity type referred by the ToRole for (int i = 0; i < roleElement.RoleProperties.Count; i++) { // Once we find that the properties in the constraint are not a subset of the // Key, one need not search for it every time if (isSubsetOfKeyProperties) { bool foundKeyProperty = false; // All properties that are defined in ToProperties must be the key property on the entity type for (int j = 0; j < itemType.KeyProperties.Count; j++) { if (itemType.KeyProperties[j].Property == roleElement.RoleProperties[i].Property) { foundKeyProperty = true; break; } } if (!foundKeyProperty) { isKeyProperty = false; isSubsetOfKeyProperties = false; } } areAllPropertiesNullable &= roleElement.RoleProperties[i].Property.Nullable; isAnyPropertyNullable |= roleElement.RoleProperties[i].Property.Nullable; } }
/// <summary> /// Resolves the given property names to the property in the item /// Also checks whether the properties form the key for the given type and whether all the properties are nullable or not /// </summary> /// <param name="roleElement"></param> /// <param name="itemType"></param> /// <param name="isKeyProperty"></param> /// <param name="areAllPropertiesNullable"></param> /// <param name="isSubsetOfKeyProperties"></param> private static void IsKeyProperty( ReferentialConstraintRoleElement roleElement, SchemaEntityType itemType, out bool isKeyProperty, out bool areAllPropertiesNullable, out bool isAnyPropertyNullable, out bool isSubsetOfKeyProperties) { isKeyProperty = true; areAllPropertiesNullable = true; isAnyPropertyNullable = false; isSubsetOfKeyProperties = true; if (itemType.KeyProperties.Count != roleElement.RoleProperties.Count) { isKeyProperty = false; } // Checking that ToProperties must be the key properties in the entity type referred by the ToRole for (var i = 0; i < roleElement.RoleProperties.Count; i++) { // Once we find that the properties in the constraint are not a subset of the // Key, one need not search for it every time if (isSubsetOfKeyProperties) { var foundKeyProperty = false; // All properties that are defined in ToProperties must be the key property on the entity type for (var j = 0; j < itemType.KeyProperties.Count; j++) { if (itemType.KeyProperties[j].Property == roleElement.RoleProperties[i].Property) { foundKeyProperty = true; break; } } if (!foundKeyProperty) { isKeyProperty = false; isSubsetOfKeyProperties = false; } } areAllPropertiesNullable &= roleElement.RoleProperties[i].Property.Nullable; isAnyPropertyNullable |= roleElement.RoleProperties[i].Property.Nullable; } }
/// <summary> /// Handler for the EntityType element /// </summary> /// <param name="reader">xml reader currently positioned at EntityType element</param> private void HandleEntityTypeElement(XmlReader reader) { Debug.Assert(reader != null); SchemaEntityType itemType = new SchemaEntityType(this); itemType.Parse(reader); TryAddType(itemType, true/*doNotAddErrorForEmptyName*/); }
private static bool TypeIsSubTypeOf(SchemaEntityType itemType, Dictionary<SchemaEntityType, EntityContainerEntitySet> baseEntitySetTypes, out EntityContainerEntitySet set) { if (itemType.IsTypeHierarchyRoot) { // can't be a sub type if we are a base type set = null; return false; } // walk up the hierarchy looking for a base that is the base type of an entityset for (SchemaEntityType baseType = itemType.BaseType as SchemaEntityType; baseType != null; baseType = baseType.BaseType as SchemaEntityType) { if (baseEntitySetTypes.ContainsKey(baseType)) { set = baseEntitySetTypes[baseType]; return true; } } set = null; return false; }
/// <summary> /// Constructs an EntityContainerAssociationSetEnd /// </summary> /// <param name="parentElement">Reference to the schema element.</param> public EntityKeyElement( SchemaEntityType parentElement ) : base( parentElement ) { }
private static bool TypeDefinesNewConcurrencyProperties(SchemaEntityType itemType) { foreach (StructuredProperty property in itemType.Properties) { if (property.Type is ScalarType && MetadataHelper.GetConcurrencyMode(property.TypeUsage) != ConcurrencyMode.None) { return true; } } return false; }
/// <summary> /// validate the following negative scenarios: /// ReturnType="Collection(EntityTypeA)" /// ReturnType="Collection(EntityTypeA)" EntitySet="ESet.EType is not oftype EntityTypeA" /// EntitySet="A" /// ReturnType="Collection(ComplexTypeA)" EntitySet="something" /// ReturnType="Collection(ComplexTypeA)", but the ComplexTypeA has a nested complexType property, this scenario will be handle in the runtime /// </summary> private void ValidateFunctionImportReturnType(SchemaElement owner, SchemaType returnType, EntityContainerEntitySet entitySet, bool entitySetPathDefined) { // If entity type, verify specification of entity set and that the type is appropriate for the entity set SchemaEntityType entityType = returnType as SchemaEntityType; if (entitySet != null && entitySetPathDefined) { owner.AddError(ErrorCode.FunctionImportEntitySetAndEntitySetPathDeclared, EdmSchemaErrorSeverity.Error, Strings.FunctionImportEntitySetAndEntitySetPathDeclared(this.FQName)); } if (null != entityType) { // entity type if (null == entitySet) { // ReturnType="Collection(EntityTypeA)" owner.AddError(ErrorCode.FunctionImportReturnsEntitiesButDoesNotSpecifyEntitySet, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FunctionImportReturnEntitiesButDoesNotSpecifyEntitySet(this.FQName)); } else if (null != entitySet.EntityType && !entityType.IsOfType(entitySet.EntityType)) { // ReturnType="Collection(EntityTypeA)" EntitySet="ESet.EType is not oftype EntityTypeA" owner.AddError(ErrorCode.FunctionImportEntityTypeDoesNotMatchEntitySet, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FunctionImportEntityTypeDoesNotMatchEntitySet( this.FQName, entitySet.EntityType.FQName, entitySet.Name)); } } else { // complex type SchemaComplexType complexType = returnType as SchemaComplexType; if (complexType != null) { if (entitySet != null || entitySetPathDefined) { // ReturnType="Collection(ComplexTypeA)" EntitySet="something" owner.AddError( ErrorCode.ComplexTypeAsReturnTypeAndDefinedEntitySet, EdmSchemaErrorSeverity.Error, owner.LineNumber, owner.LinePosition, System.Data.Entity.Strings.ComplexTypeAsReturnTypeAndDefinedEntitySet(this.FQName, complexType.Name)); } } else { Debug.Assert(returnType == null || returnType is ScalarType || returnType is SchemaEnumType || returnType is Relationship, "null return type, scalar return type, enum return type or relationship expected here."); // scalar type or no return type if (entitySet != null || entitySetPathDefined) { // EntitySet="A" owner.AddError(ErrorCode.FunctionImportSpecifiesEntitySetButDoesNotReturnEntityType, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FunctionImportSpecifiesEntitySetButNotEntityType(this.FQName)); } } } }