internal override bool ParseSingleElement(ICollection <XName> unprocessedElements, XElement elem) { if (elem.Name.LocalName == EndProperty.ElementName) { var ep = new EndProperty(this, elem); ep.Parse(unprocessedElements); _endProperties.Add(ep); } else if (elem.Name.LocalName == Condition.ElementName) { var c = new Condition(this, elem); c.Parse(unprocessedElements); _conditions.Add(c); } else if (elem.Name.LocalName == QueryView.ElementName) { Debug.Assert( _queryView == null, "There could only be 1 instance of QueryView element inside AssociationSetMapping element."); _queryView = new QueryView(this, elem); _queryView.Parse(unprocessedElements); } else { return(base.ParseSingleElement(unprocessedElements, elem)); } return(true); }
/// <summary> /// Creates a ScalarProperty in the given EndProperty. /// </summary> /// <param name="end">The EndProperty to place this ScalarProperty; cannot be null.</param> /// <param name="entityProperty">This must be a valid Property from the C-Model.</param> /// <param name="tableColumn">This must be a valid Property from the S-Model.</param> /// <param name="enforceConstraints">If true checks/updates conditions on association mappings and referential constraints</param> internal CreateEndScalarPropertyCommand( EndProperty endProperty, Property entityProperty, Property tableColumn, bool enforceConstraints) { Initialize(entityProperty, tableColumn, enforceConstraints); CommandValidation.ValidateEndProperty(endProperty); _endProperty = endProperty; }
protected override void InvokeInternal(CommandProcessorContext cpc) { var end = new EndProperty(AssociationSetMapping, null); end.Name.SetRefName(AssociationSetEnd); AssociationSetMapping.AddEndProperty(end); XmlModelHelper.NormalizeAndResolve(end); Debug.Assert(end.Name.Target != null, "Could not resolve AssociationSetEnd in an EndProperty"); _created = end; }
/// <summary> /// Normalize a refName where the refName is a child of a AssociationSetMapping /// </summary> /// <param name="asm"></param> /// <param name="ep"></param> /// <param name="parent"></param> /// <param name="refName"></param> /// <returns></returns> private static NormalizedName NormalizePropertyNameRelativeToAssociationSetMapping( AssociationSetMapping asm, EndProperty ep, EFElement parent, string refName) { NormalizedName nn = null; if (ep != null && asm != null) { var prop = parent as ScalarProperty; Debug.Assert(prop != null, "parent should be a ScalarProperty"); if (ep.Name.Status == BindingStatus.Known) { nn = NormalizeNameFromAssociationSetEnd(ep.Name.Target, parent, refName); } } return(nn); }
internal void AddEndProperty(EndProperty ep) { _endProperties.Add(ep); }
internal override bool ParseSingleElement(ICollection<XName> unprocessedElements, XElement elem) { if (elem.Name.LocalName == EndProperty.ElementName) { var ep = new EndProperty(this, elem); ep.Parse(unprocessedElements); _endProperties.Add(ep); } else if (elem.Name.LocalName == Condition.ElementName) { var c = new Condition(this, elem); c.Parse(unprocessedElements); _conditions.Add(c); } else if (elem.Name.LocalName == QueryView.ElementName) { Debug.Assert( _queryView == null, "There could only be 1 instance of QueryView element inside AssociationSetMapping element."); _queryView = new QueryView(this, elem); _queryView.Parse(unprocessedElements); } else { return base.ParseSingleElement(unprocessedElements, elem); } return true; }
internal AssociationEndIdentity(EndProperty endProp) { _propertyIdentities = AssociationPropertyIdentity.CreateIdentitiesFromAssociationEndProperty(endProp); }
protected override void ProcessPreReqCommands() { // if we don't have an EndProperty, see if there is a prereq registered; don't try if we have the ASM and ASE // since this means that we should create an end later inside Invoke() if (_associationSetMapping == null && _associationSetEnd == null && _endProperty == null) { var prereq = GetPreReqCommand(CreateEndPropertyCommand.PrereqId) as CreateEndPropertyCommand; if (prereq != null) { _endProperty = prereq.EndProperty; } Debug.Assert(_endProperty != null, "We didn't get a good EndProperty out of the Command"); } }
/// <summary> /// Creates a ScalarProperty in the given EndProperty. /// </summary> /// <param name="end">The EndProperty to place this ScalarProperty; cannot be null.</param> /// <param name="entityProperty">This must be a valid Property from the C-Model.</param> /// <param name="tableColumn">This must be a valid Property from the S-Model.</param> /// <returns></returns> internal CreateEndScalarPropertyCommand(EndProperty endProperty, Property entityProperty, Property tableColumn) : this(endProperty, entityProperty, tableColumn, true) { }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (_endProperty == null) { var cmd = new CreateEndPropertyCommand(_associationSetMapping, _associationSetEnd); CommandProcessor.InvokeSingleCommand(cpc, cmd); _endProperty = cmd.EndProperty; } Debug.Assert(_endProperty != null, "_endProperty should not be null"); if (_endProperty == null) { throw new CannotLocateParentItemException(); } var sp = new ScalarProperty(_endProperty, null); sp.Name.SetRefName(_entityProperty); sp.ColumnName.SetRefName(_tableColumn); _endProperty.AddScalarProperty(sp); XmlModelHelper.NormalizeAndResolve(sp); if (_enforceConstraints) { var asm = _endProperty.Parent as AssociationSetMapping; Debug.Assert(asm != null, "_endProperty parent is not an AssociationSetMapping"); EnforceAssociationSetMappingRules.AddRule(cpc, asm); var assoc = asm.TypeName.Target; Debug.Assert(assoc != null, "_endProperty parent has a null Association"); if (assoc != null) { InferReferentialConstraints.AddRule(cpc, assoc); } } _created = sp; }
internal static void ValidateEndProperty(EndProperty end) { ValidateEFElement(end); }
/// <summary> /// Normalize a refName where the refName is a child of a AssociationSetMapping /// </summary> /// <param name="asm"></param> /// <param name="ep"></param> /// <param name="parent"></param> /// <param name="refName"></param> /// <returns></returns> private static NormalizedName NormalizePropertyNameRelativeToAssociationSetMapping( AssociationSetMapping asm, EndProperty ep, EFElement parent, string refName) { NormalizedName nn = null; if (ep != null && asm != null) { var prop = parent as ScalarProperty; Debug.Assert(prop != null, "parent should be a ScalarProperty"); if (ep.Name.Status == BindingStatus.Known) { nn = NormalizeNameFromAssociationSetEnd(ep.Name.Target, parent, refName); } } return nn; }
private EndProperty CloneEndProperty( CommandProcessorContext cpc, EndProperty endToClone, AssociationSetMapping asmInExistingArtifact, AssociationSetEnd aseInExistingArtifact, Dictionary<EntityType, EntityType> tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact) { var createEnd = new CreateEndPropertyCommand(asmInExistingArtifact, aseInExistingArtifact); CommandProcessor.InvokeSingleCommand(cpc, createEnd); var endInExistingArtifact = createEnd.EndProperty; if (null == endInExistingArtifact) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseCannotCreateAssociationSetMappingEndProperty, aseInExistingArtifact.ToPrettyString())); } var existingArtifact = cpc.Artifact; Debug.Assert(existingArtifact != null, "existingArtifact is null for endToClone " + endToClone.ToPrettyString()); foreach (var sp in endToClone.ScalarProperties()) { if (null == sp.Name.Target) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseScalarPropertyNoNameTarget, sp.ToPrettyString())); } if (null == sp.ColumnName.Target) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseScalarPropertyNoColumnNameTarget, sp.ToPrettyString())); } var spCSideEntityTypeinTempArtifact = sp.Name.Target.EntityType as ConceptualEntityType; if (null == spCSideEntityTypeinTempArtifact) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseAssociationSetMappingCannotFindEntityTypeForProperty, sp.Name.Target.ToPrettyString())); } var spSSideEntityTypeinTempArtifact = sp.ColumnName.Target.EntityType as StorageEntityType; if (null == spSSideEntityTypeinTempArtifact) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseAssociationSetMappingCannotFindEntityTypeForProperty, sp.ColumnName.Target.ToPrettyString())); } var csdlEntityTypeInExistingArtifact = FindMatchingConceptualEntityTypeInExistingArtifact( spCSideEntityTypeinTempArtifact, tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact); if (null == csdlEntityTypeInExistingArtifact) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseAssociationSetMappingCannotFindMatchingEntityType, sp.ToPrettyString(), spCSideEntityTypeinTempArtifact.ToPrettyString())); } var ssdlEntityTypeInExistingArtifact = FindMatchingStorageEntityTypeInExistingArtifact(spSSideEntityTypeinTempArtifact); if (null == ssdlEntityTypeInExistingArtifact) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseAssociationSetMappingCannotFindMatchingEntityType, sp.ToPrettyString(), spSSideEntityTypeinTempArtifact.ToPrettyString())); } var entityProperty = FindMatchingPropertyInExistingArtifactEntityType(sp.Name.Target, csdlEntityTypeInExistingArtifact); if (null == entityProperty) { // Cannot find matching property - it must have been unmapped. // So try to create a new mapped property to which to attach // this association. // First find S-side Property in temp artifact to which the C-side // Property identified in the AssociationSetMapping is mapped // (Note: cannot use just sp.ColumnName.Target as the S-side Property // used in the AssociationSetMapping can be different from what is used // for the EntitySetMapping in the temp artifact and it is this latter // we need to replicate here). Property sSidePropertyToBeMappedInTempArtifact = null; foreach (var spInTempArtifact in sp.Name.Target.GetAntiDependenciesOfType<ScalarProperty>()) { // Ensure that S-side ScalarProperty is from an EntitySetMapping (and not // an AssociationSetMapping) in the temp artifact. // Can use first one as in temp artifact there is 1:1 mapping. if (null != spInTempArtifact.GetParentOfType(typeof(EntitySetMapping))) { if (null != spInTempArtifact.ColumnName && null != spInTempArtifact.ColumnName.Target) { if (null == sSidePropertyToBeMappedInTempArtifact) { sSidePropertyToBeMappedInTempArtifact = spInTempArtifact.ColumnName.Target; } else { // error in temp artifact - there's more than 1 EntitySetMapping ScalarProperty // mapped to the C-side Property Debug.Fail( "C-side Property " + sp.Name.Target.ToPrettyString() + " has more than 1 ScalarProperty anti-dep with an EntitySetMapping parent. Should be at most 1."); break; } } } } if (null == sSidePropertyToBeMappedInTempArtifact) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseAssociationSetMappingCannotFindSSideForCSideProperty, sp.ToPrettyString(), sp.Name.Target.ToPrettyString())); } // Now find the matching S-side Property in the existing artifact var sSidePropertyToBeMappedInExistingArtifact = FindSSidePropInExistingArtifact(sSidePropertyToBeMappedInTempArtifact); if (null == sSidePropertyToBeMappedInExistingArtifact) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseAssociationSetMappingCannotFindMatchingSSideProperty, sp.ToPrettyString(), sSidePropertyToBeMappedInTempArtifact.ToPrettyString())); } // Now create a new C-side Property in the existing artifact mapped // to the S-side Property we just found entityProperty = CreateNewConceptualPropertyAndMapping( cpc, sp.Name.Target, sSidePropertyToBeMappedInTempArtifact, csdlEntityTypeInExistingArtifact); if (null == entityProperty) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseAssociationSetMappingCannotFindOrCreateMatchingProperty, sp.ToPrettyString(), sp.Name.Target.ToPrettyString(), csdlEntityTypeInExistingArtifact.ToPrettyString())); } } var tableColumn = FindMatchingPropertyInExistingArtifactEntityType(sp.ColumnName.Target, ssdlEntityTypeInExistingArtifact); if (null == tableColumn) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseAssociationSetMappingCannotFindMatchingProperty, sp.ToPrettyString(), sp.ColumnName.Target.ToPrettyString(), ssdlEntityTypeInExistingArtifact.ToPrettyString())); } var createScalar = new CreateEndScalarPropertyCommand(endInExistingArtifact, entityProperty, tableColumn); CommandProcessor.InvokeSingleCommand(cpc, createScalar); var existingScalarProp = createScalar.ScalarProperty; if (null == existingScalarProp) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseCannotCreateAssociationSetMappingScalarProperty, entityProperty.ToPrettyString(), tableColumn.ToPrettyString())); } } return endInExistingArtifact; }