Exemple #1
0
        private void HandleEntitySetElement(XmlReader reader)
        {
            DebugCheck.NotNull(reader);
            var set = new EntityContainerEntitySet(this);

            set.Parse(reader);
            Members.Add(set, true, Strings.DuplicateEntityContainerMemberName);
        }
        internal override SchemaElement Clone(SchemaElement parentElement)
        {
            var entitySet = new EntityContainerEntitySet((EntityContainer)parentElement);
            entitySet._definingQueryElement = _definingQueryElement;
            entitySet._entityType = _entityType;
            entitySet._schema = _schema;
            entitySet._table = _table;
            entitySet.Name = Name;

            return entitySet;
        }
Exemple #3
0
        /// <summary>
        ///     Adds a child EntitySet's tableKey (Schema/Table combination) to the validation collection
        ///     This is used to validate that no child EntitySets share a Schema.Table combination
        /// </summary>
        private void CheckForDuplicateTableMapping(HashSet <string> tableKeys, EntityContainerEntitySet entitySet)
        {
            string schema;
            string table;

            if (String.IsNullOrEmpty(entitySet.DbSchema))
            {
                // if there is no specified DbSchema, use the parent EntityContainer's name
                schema = Name;
            }
            else
            {
                schema = entitySet.DbSchema;
            }

            if (String.IsNullOrEmpty(entitySet.Table))
            {
                // if there is no specified Table, use the EntitySet's name
                table = entitySet.Name;
            }
            else
            {
                table = entitySet.Table;
            }

            // create a key using the DbSchema and Table
            var tableKey = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", schema, table);

            if (entitySet.DefiningQuery != null)
            {
                // don't consider the schema name for defining queries, because
                // we can't say for sure that it is the same as the entity container
                // so in this example
                //
                // <EntityContainer Name="dbo">
                //   <EntitySet Name="ByVal">
                //     <DefiningQuery>Select col1 from dbi.ByVal</DefiningQuery>
                //   </EntitySet>
                //   <EntitySet Name="ByVal1" Table="ByVal"/>
                //   ...
                //
                // ByVal and ByVal1 should not conflict in our check
                tableKey = entitySet.Name;
            }

            var alreadyExisted = !tableKeys.Add(tableKey);

            if (alreadyExisted)
            {
                entitySet.AddError(
                    ErrorCode.AlreadyDefined, EdmSchemaErrorSeverity.Error, Strings.DuplicateEntitySetTable(entitySet.Name, schema, table));
            }
        }
Exemple #4
0
        /// <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 (_entitySet == null)
            {
                _entitySet = ParentElement.ParentElement.FindEntitySet(_unresolvedEntitySetName);
                if (_entitySet == null)
                {
                    AddError(
                        ErrorCode.InvalidEndEntitySet, EdmSchemaErrorSeverity.Error,
                        Strings.InvalidEntitySetNameReference(_unresolvedEntitySetName, Name));
                }
            }
        }
Exemple #5
0
        /// <summary>
        ///     Create and add a EntityContainerEnd from the IRelationshipEnd provided
        /// </summary>
        /// <param name="relationshipEnd"> The relationship end of the end to add. </param>
        /// <param name="entitySet"> The entitySet to associate with the relationship end. </param>
        protected override void AddEnd(IRelationshipEnd relationshipEnd, EntityContainerEntitySet entitySet)
        {
            DebugCheck.NotNull(relationshipEnd);
            Debug.Assert(!_relationshipEnds.ContainsKey(relationshipEnd.Name));
            // we expect set to be null sometimes

            var end = new EntityContainerAssociationSetEnd(this);

            end.Role            = relationshipEnd.Name;
            end.RelationshipEnd = relationshipEnd;

            end.EntitySet = entitySet;
            if (end.EntitySet != null)
            {
                _relationshipEnds.Add(end.Role, end);
            }
        }
        /// <summary>
        ///     If the role name is missing but an entity set is given, figure out what the
        ///     relationship end should be
        /// </summary>
        /// <param name="set"> The given EntitySet </param>
        /// <returns> The appropriate relationship end </returns>
        private IRelationshipEnd InferRelationshipEnd(EntityContainerEntitySet set)
        {
            DebugCheck.NotNull(set);

            if (ParentElement.Relationship == null)
            {
                return(null);
            }

            var possibleEnds = new List <IRelationshipEnd>();

            foreach (var end in ParentElement.Relationship.Ends)
            {
                if (set.EntityType.IsOfType(end.Type))
                {
                    possibleEnds.Add(end);
                }
            }

            if (possibleEnds.Count == 1)
            {
                return(possibleEnds[0]);
            }
            else if (possibleEnds.Count == 0)
            {
                // no matchs
                AddError(
                    ErrorCode.FailedInference, EdmSchemaErrorSeverity.Error,
                    Strings.InferRelationshipEndFailedNoEntitySetMatch(
                        set.Name, ParentElement.Name, ParentElement.Relationship.FQName, set.EntityType.FQName,
                        ParentElement.ParentElement.FQName));
            }
            else
            {
                // ambiguous
                AddError(
                    ErrorCode.FailedInference, EdmSchemaErrorSeverity.Error,
                    Strings.InferRelationshipEndAmbiguous(
                        set.Name, ParentElement.Name, ParentElement.Relationship.FQName, set.EntityType.FQName,
                        ParentElement.ParentElement.FQName));
            }

            return(null);
        }
Exemple #7
0
        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 (var 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);
        }
Exemple #8
0
        internal void ResolveEntitySet(SchemaElement owner, string unresolvedEntitySet, ref EntityContainerEntitySet entitySet)
        {
            Debug.Assert(IsFunctionImport, "Only FunctionImport elkements specify EntitySets");
            Debug.Assert(null != _container, "function imports must know container");

            // resolve entity set
            if (null == entitySet &&
                null != unresolvedEntitySet)
            {
                entitySet = _container.FindEntitySet(unresolvedEntitySet);

                if (null == entitySet)
                {
                    owner.AddError(
                        ErrorCode.FunctionImportUnknownEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        Strings.FunctionImportUnknownEntitySet(unresolvedEntitySet, FQName));
                }
            }
        }
 protected abstract void AddEnd(IRelationshipEnd relationshipEnd, EntityContainerEntitySet entitySet);
        /// <summary>
        /// If the role name is missing but an entity set is given, figure out what the
        /// relationship end should be
        /// </summary>
        /// <param name="set">The given EntitySet</param>
        /// <returns>The appropriate relationship end</returns>
        private IRelationshipEnd InferRelationshipEnd(EntityContainerEntitySet set)
        {
            Debug.Assert(set != null, "set parameter is null");

            if (ParentElement.Relationship == null)
            {
                return null;
            }

            var possibleEnds = new List<IRelationshipEnd>();
            foreach (var end in ParentElement.Relationship.Ends)
            {
                if (set.EntityType.IsOfType(end.Type))
                {
                    possibleEnds.Add(end);
                }
            }

            if (possibleEnds.Count == 1)
            {
                return possibleEnds[0];
            }
            else if (possibleEnds.Count == 0)
            {
                // no matchs
                AddError(
                    ErrorCode.FailedInference, EdmSchemaErrorSeverity.Error,
                    Strings.InferRelationshipEndFailedNoEntitySetMatch(
                        set.Name, ParentElement.Name, ParentElement.Relationship.FQName, set.EntityType.FQName,
                        ParentElement.ParentElement.FQName));
            }
            else
            {
                // ambiguous
                AddError(
                    ErrorCode.FailedInference, EdmSchemaErrorSeverity.Error,
                    Strings.InferRelationshipEndAmbiguous(
                        set.Name, ParentElement.Name, ParentElement.Relationship.FQName, set.EntityType.FQName,
                        ParentElement.ParentElement.FQName));
            }

            return null;
        }
 /// <summary>
 ///     Constructs an EntityContainerEntitySet
 /// </summary>
 /// <param name="parentElement"> Reference to the schema element. </param>
 public EntityContainerEntitySetDefiningQuery(EntityContainerEntitySet parentElement)
     : base(parentElement)
 {
 }
 /// <summary>
 /// Constructs an EntityContainerEntitySet
 /// </summary>
 /// <param name="parentElement">Reference to the schema element.</param>
 public EntityContainerEntitySetDefiningQuery(EntityContainerEntitySet parentElement)
     : base(parentElement)
 {
 }
        internal override SchemaElement Clone(SchemaElement parentElement)
        {
            var entitySet = new EntityContainerEntitySet((EntityContainer)parentElement);
            entitySet._definingQueryElement = _definingQueryElement;
            entitySet._entityType = _entityType;
            entitySet._schema = _schema;
            entitySet._table = _table;
            entitySet.Name = Name;

            return entitySet;
        }
Exemple #14
0
        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 (var 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>
        /// 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 (_entitySet == null)
            {
                _entitySet = ParentElement.ParentElement.FindEntitySet(_unresolvedEntitySetName);
                if (_entitySet == null)
                {
                    AddError(
                        ErrorCode.InvalidEndEntitySet, EdmSchemaErrorSeverity.Error,
                        Strings.InvalidEntitySetNameReference(_unresolvedEntitySetName, Name));
                }
            }
        }
Exemple #16
0
 protected abstract void AddEnd(IRelationshipEnd relationshipEnd, EntityContainerEntitySet entitySet);
        /// <summary>
        ///     Create and add a EntityContainerEnd from the IRelationshipEnd provided
        /// </summary>
        /// <param name="relationshipEnd"> The relationship end of the end to add. </param>
        /// <param name="entitySet"> The entitySet to associate with the relationship end. </param>
        protected override void AddEnd(IRelationshipEnd relationshipEnd, EntityContainerEntitySet entitySet)
        {
            Debug.Assert(relationshipEnd != null);
            Debug.Assert(!_relationshipEnds.ContainsKey(relationshipEnd.Name));
            // we expect set to be null sometimes

            var end = new EntityContainerAssociationSetEnd(this);
            end.Role = relationshipEnd.Name;
            end.RelationshipEnd = relationshipEnd;

            end.EntitySet = entitySet;
            if (end.EntitySet != null)
            {
                _relationshipEnds.Add(end.Role, end);
            }
        }
        /// <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
            var entityType = returnType as SchemaEntityType;

            if (entitySet != null && entitySetPathDefined)
            {
                owner.AddError(
                    ErrorCode.FunctionImportEntitySetAndEntitySetPathDeclared,
                    EdmSchemaErrorSeverity.Error,
                    Strings.FunctionImportEntitySetAndEntitySetPathDeclared(FQName));
            }

            if (null != entityType)
            {
                // entity type
                if (null == entitySet)
                {
                    // ReturnType="Collection(EntityTypeA)"
                    owner.AddError(
                        ErrorCode.FunctionImportReturnsEntitiesButDoesNotSpecifyEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        Strings.FunctionImportReturnEntitiesButDoesNotSpecifyEntitySet(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,
                        Strings.FunctionImportEntityTypeDoesNotMatchEntitySet(
                            FQName, entitySet.EntityType.FQName, entitySet.Name));
                }
            }
            else
            {
                // complex type
                var 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,
                            Strings.ComplexTypeAsReturnTypeAndDefinedEntitySet(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,
                            Strings.FunctionImportSpecifiesEntitySetButNotEntityType(FQName));
                    }
                }
            }
        }
 private void ValidateFunctionImportReturnType(
     SchemaElement owner, SchemaType returnType, CollectionKind returnTypeCollectionKind, EntityContainerEntitySet entitySet,
     bool entitySetPathDefined)
 {
     if (returnType != null
         && !ReturnTypeMeetsFunctionImportBasicRequirements(returnType, returnTypeCollectionKind))
     {
         owner.AddError(
             ErrorCode.FunctionImportUnsupportedReturnType,
             EdmSchemaErrorSeverity.Error,
             owner,
             GetReturnTypeErrorMessage(Name)
             );
     }
     ValidateFunctionImportReturnType(owner, returnType, entitySet, entitySetPathDefined);
 }
        internal void ResolveEntitySet(SchemaElement owner, string unresolvedEntitySet, ref EntityContainerEntitySet entitySet)
        {
            Debug.Assert(IsFunctionImport, "Only FunctionImport elkements specify EntitySets");
            Debug.Assert(null != _container, "function imports must know container");

            // resolve entity set
            if (null == entitySet
                && null != unresolvedEntitySet)
            {
                entitySet = _container.FindEntitySet(unresolvedEntitySet);

                if (null == entitySet)
                {
                    owner.AddError(
                        ErrorCode.FunctionImportUnknownEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        Strings.FunctionImportUnknownEntitySet(unresolvedEntitySet, FQName));
                }
            }
        }
Exemple #21
0
 private void HandleEntitySetElement(XmlReader reader)
 {
     DebugCheck.NotNull(reader);
     var set = new EntityContainerEntitySet(this);
     set.Parse(reader);
     Members.Add(set, true, Strings.DuplicateEntityContainerMemberName);
 }
Exemple #22
0
 private void ValidateFunctionImportReturnType(
     SchemaElement owner, SchemaType returnType, CollectionKind returnTypeCollectionKind, EntityContainerEntitySet entitySet,
     bool entitySetPathDefined)
 {
     if (returnType != null &&
         !ReturnTypeMeetsFunctionImportBasicRequirements(returnType, returnTypeCollectionKind))
     {
         owner.AddError(
             ErrorCode.FunctionImportUnsupportedReturnType,
             EdmSchemaErrorSeverity.Error,
             owner,
             GetReturnTypeErrorMessage(Name)
             );
     }
     ValidateFunctionImportReturnType(owner, returnType, entitySet, entitySetPathDefined);
 }
Exemple #23
0
        /// <summary>
        ///     Adds a child EntitySet's tableKey (Schema/Table combination) to the validation collection
        ///     This is used to validate that no child EntitySets share a Schema.Table combination
        /// </summary>
        private void CheckForDuplicateTableMapping(HashSet<string> tableKeys, EntityContainerEntitySet entitySet)
        {
            string schema;
            string table;

            if (String.IsNullOrEmpty(entitySet.DbSchema))
            {
                // if there is no specified DbSchema, use the parent EntityContainer's name
                schema = Name;
            }
            else
            {
                schema = entitySet.DbSchema;
            }

            if (String.IsNullOrEmpty(entitySet.Table))
            {
                // if there is no specified Table, use the EntitySet's name
                table = entitySet.Name;
            }
            else
            {
                table = entitySet.Table;
            }

            // create a key using the DbSchema and Table
            var tableKey = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", schema, table);
            if (entitySet.DefiningQuery != null)
            {
                // don't consider the schema name for defining queries, because
                // we can't say for sure that it is the same as the entity container
                // so in this example
                //
                // <EntityContainer Name="dbo">
                //   <EntitySet Name="ByVal">
                //     <DefiningQuery>Select col1 from dbi.ByVal</DefiningQuery>
                //   </EntitySet>
                //   <EntitySet Name="ByVal1" Table="ByVal"/>
                //   ...
                //
                // ByVal and ByVal1 should not conflict in our check
                tableKey = entitySet.Name;
            }

            var alreadyExisted = !tableKeys.Add(tableKey);
            if (alreadyExisted)
            {
                entitySet.AddError(
                    ErrorCode.AlreadyDefined, EdmSchemaErrorSeverity.Error, Strings.DuplicateEntitySetTable(entitySet.Name, schema, table));
            }
        }
Exemple #24
0
        /// <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
            var entityType = returnType as SchemaEntityType;

            if (entitySet != null && entitySetPathDefined)
            {
                owner.AddError(
                    ErrorCode.FunctionImportEntitySetAndEntitySetPathDeclared,
                    EdmSchemaErrorSeverity.Error,
                    Strings.FunctionImportEntitySetAndEntitySetPathDeclared(FQName));
            }

            if (null != entityType)
            {
                // entity type
                if (null == entitySet)
                {
                    // ReturnType="Collection(EntityTypeA)"
                    owner.AddError(
                        ErrorCode.FunctionImportReturnsEntitiesButDoesNotSpecifyEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        Strings.FunctionImportReturnEntitiesButDoesNotSpecifyEntitySet(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,
                        Strings.FunctionImportEntityTypeDoesNotMatchEntitySet(
                            FQName, entitySet.EntityType.FQName, entitySet.Name));
                }
            }
            else
            {
                // complex type
                var 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,
                            Strings.ComplexTypeAsReturnTypeAndDefinedEntitySet(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,
                            Strings.FunctionImportSpecifiesEntitySetButNotEntityType(FQName));
                    }
                }
            }
        }