internal override void RetrieveReferentialConstraintProperties(
     Dictionary <string, KeyValuePair <object, IntBox> > properties,
     HashSet <object> visited)
 {
     if (this._wrappedCachedValue.Entity == null)
     {
         return;
     }
     foreach (ReferentialConstraint referentialConstraint in ((AssociationType)this.RelationMetadata).ReferentialConstraints)
     {
         if (referentialConstraint.ToRole == this.FromEndMember)
         {
             if (visited.Contains((object)this._wrappedCachedValue))
             {
                 throw new InvalidOperationException(Strings.RelationshipManager_CircularRelationshipsWithReferentialConstraints);
             }
             visited.Add((object)this._wrappedCachedValue);
             Dictionary <string, KeyValuePair <object, IntBox> > properties1;
             this._wrappedCachedValue.RelationshipManager.RetrieveReferentialConstraintProperties(out properties1, visited, true);
             for (int index = 0; index < referentialConstraint.FromProperties.Count; ++index)
             {
                 EntityEntry.AddOrIncreaseCounter(referentialConstraint, properties, referentialConstraint.ToProperties[index].Name, properties1[referentialConstraint.FromProperties[index].Name].Key);
             }
         }
     }
 }
Example #2
0
        // Method used to retrieve properties from principal entities.
        // NOTE: 'properties' list is modified in this method and may already contains some properties.
        internal override void RetrieveReferentialConstraintProperties(
            Dictionary <string, KeyValuePair <object, IntBox> > properties, HashSet <object> visited)
        {
            DebugCheck.NotNull(properties);

            if (_wrappedCachedValue.Entity != null)
            {
                // Dictionary< propertyName, <propertyValue, counter>>
                Dictionary <string, KeyValuePair <object, IntBox> > retrievedProperties;

                // PERFORMANCE: ReferentialConstraints collection in typical scenario is very small (1-3 elements)
                foreach (var constraint in ((AssociationType)RelationMetadata).ReferentialConstraints)
                {
                    if (constraint.ToRole == FromEndMember)
                    {
                        // Detect circular references
                        if (visited.Contains(_wrappedCachedValue))
                        {
                            throw new InvalidOperationException(Strings.RelationshipManager_CircularRelationshipsWithReferentialConstraints);
                        }
                        visited.Add(_wrappedCachedValue);

                        _wrappedCachedValue.RelationshipManager.RetrieveReferentialConstraintProperties(
                            out retrievedProperties, visited, includeOwnValues: true);

                        Debug.Assert(retrievedProperties != null);
                        Debug.Assert(
                            constraint.FromProperties.Count == constraint.ToProperties.Count,
                            "Referential constraints From/To properties list have different size");

                        // Following loop rewrites properties from "retrievedProperties" into "properties".
                        // At the same time, property's name is translated from name from principal end into name from dependent end:
                        // Example: Client<C_ID> - Order<O_ID, Client_ID>
                        //          Client is principal end, Order is dependent end, Client.C_ID == Order.Client_ID
                        // Input : retrievedProperties = { "C_ID" = 123 }
                        // Output: properties = { "Client_ID" = 123 }

                        // NOTE order of properties in collections constraint.From/ToProperties is important
                        for (var i = 0; i < constraint.FromProperties.Count; ++i)
                        {
                            EntityEntry.AddOrIncreaseCounter(
                                constraint,
                                properties,
                                constraint.ToProperties[i].Name,
                                retrievedProperties[constraint.FromProperties[i].Name].Key);
                        }
                    }
                }
            }
        }