private void ProcessModificationFunction(EntityInfo info, ModificationFunction function) { if (function == null) { return; } // make sure that we don't have any extra scalars (i.e. from entities that are no longer parents of this entity) // so gather the list of all SPs we expect to be here var expectedMappedProperties = new List <Property>(); expectedMappedProperties.AddRange(info.KeyProperties); expectedMappedProperties.AddRange(info.NonKeyProperties); if (info.Parent != null) { GatherNonKeyPropertiesFromAllParents(info.Parent, expectedMappedProperties); } // remove any that aren't in our expected list foreach (var sp in function.ScalarProperties()) { if (expectedMappedProperties.Contains(sp.Name.Target) == false) { AddToDeleteList(sp); } } // make sure that we don't have any extra AssociationEnds var cet = info.EntityType; Debug.Assert(cet != null, "EntityType is not a ConceptualEntityType"); var selfAndBaseTypes = new List <ConceptualEntityType>(cet.SafeSelfAndBaseTypes); foreach (var end in function.AssociationEnds()) { var from = end.From.Target; var to = end.To.Target; if (from != null && to != null && from.Role.Target != null && to.Role.Target != null) { var fromType = from.Role.Target.Type.Target as ConceptualEntityType; var toType = to.Role.Target.Type.Target as ConceptualEntityType; Debug.Assert( from.Role.Target.Type.Target != null ? fromType != null : true, "fromType EntityType is not a ConceptualEntityType"); Debug.Assert( to.Role.Target.Type.Target != null ? toType != null : true, "toType EntityType is not a ConceptualEntityType"); if (fromType != null && toType != null) { if (selfAndBaseTypes.Contains(fromType) || selfAndBaseTypes.Contains(toType)) { continue; } } } AddToDeleteList(end); } }
internal static FunctionScalarProperty CreateFunctionScalarPropertyInAssociationEnd( ModificationFunction mf, Property entityProperty, NavigationProperty pointingNavProperty, Parameter parm, string version) { // in creating the function scalar property, we modify the AssociationEnd depending on the navigation property that is // pointing to the actual property. If we don't have this navigation property we can't do anything. Debug.Assert( pointingNavProperty != null, "We need the navigation property pointing to the property in order to create the mapping function scalar property"); if (pointingNavProperty == null) { throw new CannotLocateReferencedItemException(); } Debug.Assert(pointingNavProperty.Relationship.Target != null, "Where is the Association for this navigation property?"); if (pointingNavProperty.Relationship.Target == null) { throw new CannotLocateReferencedItemException(); } var assocSet = pointingNavProperty.Relationship.Target.AssociationSet; var navPropFromEnd = pointingNavProperty.FromRole.Target; var navPropToEnd = pointingNavProperty.ToRole.Target; Debug.Assert(null != navPropFromEnd, "Null FromRole for pointingNavProperty " + pointingNavProperty.ToPrettyString()); Debug.Assert(null != navPropToEnd, "Null ToRole for pointingNavProperty " + pointingNavProperty.ToPrettyString()); AssociationSetEnd assocSetFromEnd = null; AssociationSetEnd assocSetToEnd = null; // figure which end is which // Note: it is valid for the NavigationProperty to point to // an EntityType in the same inheritance hierarchy foreach (var end in assocSet.AssociationSetEnds()) { if (end.Role.Target == navPropFromEnd) { Debug.Assert( null == assocSetFromEnd, "pointingNavProperty From End " + navPropFromEnd.ToPrettyString() + " matches more than 1 AssociationSetEnd for AssociationSet " + assocSet.ToPrettyString()); assocSetFromEnd = end; } else if (end.Role.Target == navPropToEnd) { Debug.Assert( null == assocSetToEnd, "pointingNavProperty To End " + navPropToEnd.ToPrettyString() + " matches more than 1 AssociationSetEnd for AssociationSet " + assocSet.ToPrettyString()); assocSetToEnd = end; } } Debug.Assert(null != assocSetFromEnd, "Cannot find From end of AssociationSet " + assocSet.ToPrettyString()); Debug.Assert(null != assocSetToEnd, "Cannot find To end of AssociationSet " + assocSet.ToPrettyString()); // see if we already have this AssociationEnd FunctionAssociationEnd fae = null; foreach (var funcAssocEnd in mf.AssociationEnds()) { if (funcAssocEnd.AssociationSet.Target == assocSet && funcAssocEnd.From.Target == assocSetFromEnd && funcAssocEnd.To.Target == assocSetToEnd) { fae = funcAssocEnd; break; } } // create the association end if needed if (fae == null) { fae = new FunctionAssociationEnd(mf, null); fae.AssociationSet.SetRefName(assocSet); fae.From.SetRefName(assocSetFromEnd); fae.To.SetRefName(assocSetToEnd); mf.AddAssociationEnd(fae); XmlModelHelper.NormalizeAndResolve(fae); } Debug.Assert(fae != null, "Failed to create the AssocationEnd to house this ScalarProperty"); if (fae == null) { throw new ParentItemCreationFailureException(); } // create the SP inside this return(CreateFunctionScalarPropertyCommon(fae, entityProperty, parm, version)); }