Esempio n. 1
0
 internal static ResourceType GetDeclaringTypeForProperty(ResourceType resourceType, ResourceProperty resourceProperty, ResourceType rootType = null)
 {
     while (resourceType != rootType)
     {
         if (resourceType.TryResolvePropertiesDeclaredOnThisTypeByName(resourceProperty.Name) == resourceProperty)
         {
             return(resourceType);
         }
         resourceType = resourceType.BaseType;
     }
     return(resourceType);
 }
Esempio n. 2
0
            /// <summary>
            /// Gets and validates the ResourceAssociationSet instance when given the source association end.
            /// </summary>
            /// <param name="resourceSet">Resource set of the source association end.</param>
            /// <param name="resourceType">Resource type of the source association end.</param>
            /// <param name="navigationProperty">Resource property of the source association end.</param>
            /// <returns>ResourceAssociationSet instance.</returns>
            private ResourceAssociationSet GetAndValidateResourceAssociationSet(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty navigationProperty)
            {
                Debug.Assert(resourceSet != null, "resourceSet != null");
                Debug.Assert(resourceType != null, "resourceType != null");
                Debug.Assert(navigationProperty != null, "navigationProperty != null");
                Debug.Assert(resourceType.TryResolvePropertiesDeclaredOnThisTypeByName(navigationProperty.Name) != null, "navigationProperty must be declared on resourceType.");

                string associationSetKey = resourceSet.Name + '_' + resourceType.FullName + '_' + navigationProperty.Name;
                ResourceAssociationSet associationSet;
                if (this.associationSets.TryGetValue(associationSetKey, out associationSet))
                {
                    return associationSet;
                }

                associationSet = this.provider.GetResourceAssociationSet(resourceSet, resourceType, navigationProperty);
                if (associationSet != null)
                {
                    ResourceAssociationSetEnd relatedEnd = associationSet.GetRelatedResourceAssociationSetEnd(resourceSet, resourceType, navigationProperty);

                    // If this is a two way relationship, GetResourceAssociationSet should return the same association set when called from either end.
                    // For example, it's not valid to have the association sets {GoodCustomerSet} <-> {OrdersSet} and {BadCustomerSet} <-> {OrdersSet}
                    // because starting from {OrderSet} we won't know which customers set to resolve to.
                    if (relatedEnd.ResourceProperty != null)
                    {
                        ResourceAssociationSet reverseAssociationSet = this.provider.GetResourceAssociationSet(this.provider.ValidateResourceSet(relatedEnd.ResourceSet), relatedEnd.ResourceType, relatedEnd.ResourceProperty);
                        if (reverseAssociationSet == null || associationSet.Name != reverseAssociationSet.Name)
                        {
                            throw new InvalidOperationException(Strings.ResourceAssociationSet_BidirectionalAssociationMustReturnSameResourceAssociationSetFromBothEnd);
                        }
                    }

                    // Cache the association set for the reverse direction.
                    string reverseAssociationSetKey;
                    if (relatedEnd.ResourceProperty != null)
                    {
                        reverseAssociationSetKey = relatedEnd.ResourceSet.Name + '_' + relatedEnd.ResourceProperty.ResourceType.FullName + '_' + relatedEnd.ResourceProperty.Name;
                    }
                    else
                    {
                        reverseAssociationSetKey = relatedEnd.ResourceSet.Name + "_Null_" + resourceType.FullName + '_' + navigationProperty.Name;
                    }

                    ResourceAssociationSet conflictingAssociationSet;
                    if (this.associationSets.TryGetValue(reverseAssociationSetKey, out conflictingAssociationSet))
                    {
                        // If only one of the ends is already in the cache, we know that the provider is giving us inconsistant metadata.
                        // Make sure that if two or more AssociationSets refer to the same AssociationType, the ends must not refer to the same EntitySet.
                        // For CLR context, this could happen if multiple entity sets have entity types that have a common ancestor and the ancestor has a property of derived entity types.
                        throw new InvalidOperationException(Strings.ResourceAssociationSet_MultipleAssociationSetsForTheSameAssociationTypeMustNotReferToSameEndSets(conflictingAssociationSet.Name, associationSet.Name, relatedEnd.ResourceSet.Name));
                    }

                    this.associationSets.Add(reverseAssociationSetKey, associationSet);
                    this.associationSets.Add(associationSetKey, associationSet);
                }

                return associationSet;
            }