/// <summary> /// Adds an entity set backed by the <paramref name="resourceSet"/> to the entity container. /// </summary> /// <param name="entitySetName">The name of the entity set.</param> /// <param name="resourceSet">The resource set backing the entity set to be created.</param> /// <returns>an instance of IEdmEntitySet that just got added.</returns> /// <remarks> /// This method will also create the association sets and associations for the entity set. /// Materialization state: EntityContainers required. No change in materialization state. /// </remarks> internal IEdmEntitySet AddEntitySet(string entitySetName, ResourceSetWrapper resourceSet) { Debug.Assert(!string.IsNullOrEmpty(entitySetName), "!string.IsNullOrEmpty(entitySetName)"); Debug.Assert(resourceSet != null, "resourceSet != null"); IEdmEntitySet entitySet = new MetadataProviderEdmEntitySet(this.model, this, resourceSet); MetadataProviderUtils.ConvertCustomAnnotations(this.model, resourceSet.CustomAnnotations, entitySet); this.entitySetCache.Add(entitySetName, entitySet); return(entitySet); }
/// <summary> /// Finds the entity set that this navigation property refers to. /// </summary> /// <param name="navigationProperty">Instance of navigation property.</param> /// <returns>an instance of IEdmEntitySet that this navigation property refers to.</returns> public IEdmNavigationSource FindNavigationTarget(IEdmNavigationProperty navigationProperty) { WebUtil.CheckArgumentNull(navigationProperty, "navigationProperty"); MetadataProviderEdmEntitySet targetEntitySet = null; if (this.navigationTargetMapping == null || !this.navigationTargetMapping.TryGetValue(navigationProperty, out targetEntitySet)) { string declaringTypeName = navigationProperty.DeclaringEntityType().FullName(); ResourceType declaringResourceType = this.model.MetadataProvider.TryResolveResourceType(declaringTypeName); ResourceProperty navigationResourceProperty = declaringResourceType.TryResolvePropertiesDeclaredOnThisTypeByName(navigationProperty.Name); if (navigationResourceProperty != null && navigationResourceProperty.TypeKind == ResourceTypeKind.EntityType) { // Calling this method causes the model to load all the metadata for the given association. // Hence we do not need to add this to the target mapping explicitly this.model.PairUpNavigationProperty(this.resourceSet, declaringResourceType, navigationResourceProperty); // Since the entity set or target entity set might be hidden, the navigation target might not get added // from the previous call if (this.navigationTargetMapping != null) { this.navigationTargetMapping.TryGetValue(navigationProperty, out targetEntitySet); } } } if (this.model.Mode == MetadataProviderEdmModelMode.SelectAndExpandParsing) { // When parsing $select/$expand, the URI parser has no way of knowing which sets are visible. So, if a navigation property is found // that does not have a target entity set, then it means that the target set is hidden. To avoid disclosing the existence of the set, act // as if the property does not exist. if (targetEntitySet == null) { // We're playing a dangerous game here. We are trying to throw the SAME ERROR MESSAGE that the Uri Parser would throw // for some property that is not found. If it looks any different, a client could detect the difference and learn about // the existance of a navigation property that should have been hidden. throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidPropertyNameSpecified(navigationProperty.Name, navigationProperty.DeclaringEntityType().FullName())); } } if (this.model.Mode == MetadataProviderEdmModelMode.UriPathParsing) { // As with select and expand, when parsing the path, the URI parser has no way of knowing which sets are visible. See above. if (targetEntitySet == null) { // Same fragility as above. throw DataServiceException.CreateResourceNotFound(navigationProperty.Name); } } return(targetEntitySet); }
/// <summary> /// Adds an entity set backed by the <paramref name="resourceSet"/> to the entity container. /// </summary> /// <param name="entitySetName">The name of the entity set.</param> /// <param name="resourceSet">The resource set backing the entity set to be created.</param> /// <returns>an instance of IEdmEntitySet that just got added.</returns> /// <remarks> /// This method will also create the association sets and associations for the entity set. /// Materialization state: EntityContainers required. No change in materialization state. /// </remarks> internal IEdmEntitySet AddEntitySet(string entitySetName, ResourceSetWrapper resourceSet) { Debug.Assert(!string.IsNullOrEmpty(entitySetName), "!string.IsNullOrEmpty(entitySetName)"); Debug.Assert(resourceSet != null, "resourceSet != null"); IEdmEntitySet entitySet = new MetadataProviderEdmEntitySet(this.model, this, resourceSet); MetadataProviderUtils.ConvertCustomAnnotations(this.model, resourceSet.CustomAnnotations, entitySet); this.entitySetCache.Add(entitySetName, entitySet); return entitySet; }
/// <summary> /// Cache the entity set that the given navigation property refers to. /// </summary> /// <param name="navigationProperty">IEdmNavigationProperty that contains the navigation property metadata.</param> /// <param name="entitySet">Entityset that <paramref name="navigationProperty"/> refers to.</param> internal void EnsureNavigationTarget(IEdmNavigationProperty navigationProperty, MetadataProviderEdmEntitySet entitySet) { Debug.Assert(navigationProperty != null, "navigationProperty != null"); Debug.Assert(entitySet != null, "entitySet != null"); MetadataProviderEdmEntitySet targetEntitySet; if (this.navigationTargetMapping == null) { this.navigationTargetMapping = new Dictionary <IEdmNavigationProperty, MetadataProviderEdmEntitySet>(EqualityComparer <IEdmNavigationProperty> .Default); } if (!this.navigationTargetMapping.TryGetValue(navigationProperty, out targetEntitySet)) { // Looks like this will get called multiple types for the same navigation property in MEST scenarios. // Looking at the EdmEntitySet, the last one wins. So keeping the same behavior here. this.navigationTargetMapping.Add(navigationProperty, entitySet); } else { Debug.Assert(targetEntitySet == entitySet, "targetEntitySet == entitySet"); } }
/// <summary> /// Cache the entity set that the given navigation property refers to. /// </summary> /// <param name="navigationProperty">IEdmNavigationProperty that contains the navigation property metadata.</param> /// <param name="entitySet">Entityset that <paramref name="navigationProperty"/> refers to.</param> internal void EnsureNavigationTarget(IEdmNavigationProperty navigationProperty, MetadataProviderEdmEntitySet entitySet) { Debug.Assert(navigationProperty != null, "navigationProperty != null"); Debug.Assert(entitySet != null, "entitySet != null"); string path = navigationProperty.Name; if (!this.Type.AsElementType().IsOrInheritsFrom(navigationProperty.DeclaringType)) { path = navigationProperty.DeclaringType.FullTypeName() + '/' + path; } if (!this.navigationBindingMappings.ContainsKey(navigationProperty)) { this.navigationBindingMappings[navigationProperty] = new Dictionary <string, IEdmNavigationPropertyBinding>(); } this.navigationBindingMappings[navigationProperty][path] = new EdmNavigationPropertyBinding(navigationProperty, entitySet, new EdmPathExpression(path)); }
/// <summary> /// Cache the entity set that the given navigation property refers to. /// </summary> /// <param name="navigationProperty">IEdmNavigationProperty that contains the navigation property metadata.</param> /// <param name="entitySet">Entityset that <paramref name="navigationProperty"/> refers to.</param> internal void EnsureNavigationTarget(IEdmNavigationProperty navigationProperty, MetadataProviderEdmEntitySet entitySet) { Debug.Assert(navigationProperty != null, "navigationProperty != null"); Debug.Assert(entitySet != null, "entitySet != null"); MetadataProviderEdmEntitySet targetEntitySet; if (this.navigationTargetMapping == null) { this.navigationTargetMapping = new Dictionary<IEdmNavigationProperty, MetadataProviderEdmEntitySet>(EqualityComparer<IEdmNavigationProperty>.Default); } if (!this.navigationTargetMapping.TryGetValue(navigationProperty, out targetEntitySet)) { // Looks like this will get called multiple types for the same navigation property in MEST scenarios. // Looking at the EdmEntitySet, the last one wins. So keeping the same behavior here. this.navigationTargetMapping.Add(navigationProperty, entitySet); } else { Debug.Assert(targetEntitySet == entitySet, "targetEntitySet == entitySet"); } }