internal override bool ParseSingleElement(ICollection <XName> unprocessedElements, XElement elem) { if (elem.Name.LocalName == EntitySetMapping.ElementName) { var esm = new EntitySetMapping(this, elem); _entitySetMappings.Add(esm); esm.Parse(unprocessedElements); } else if (elem.Name.LocalName == AssociationSetMapping.ElementName) { var asm = new AssociationSetMapping(this, elem); _associationSetMappings.Add(asm); asm.Parse(unprocessedElements); } else if (elem.Name.LocalName == FunctionImportMapping.ElementName) { var fim = new FunctionImportMapping(this, elem); _functionImportMappings.Add(fim); fim.Parse(unprocessedElements); } else { return(base.ParseSingleElement(unprocessedElements, elem)); } return(true); }
private CreateEndScalarPropertyCommand( AssociationSetMapping associationSetMapping, AssociationSetEnd associationSetEnd, Property entityProperty, Property tableColumn, bool enforceConstraints) { Initialize(entityProperty, tableColumn, enforceConstraints); CommandValidation.ValidateAssociationSetMapping(associationSetMapping); CommandValidation.ValidateAssociationSetEnd(associationSetEnd); _associationSetMapping = associationSetMapping; _associationSetEnd = associationSetEnd; }
/// <summary> /// Creates a Condition in the given AssociationSetMapping. /// Valid combinations are: /// 1. Send true or false for isNull, and null for conditionValue /// 2. Send null for isNull, and a non-empty string for conditionValue /// 3. Send null for isNull, and null for conditionValue /// You cannot send non-null values to both arguments. /// </summary> /// <param name="mappingFragment">The AssociationSetMapping to place this Condition; cannot be null.</param> /// <param name="tableColumn">This must be a valid Property from the S-Model.</param> internal CreateEndConditionCommand( AssociationSetMapping associationSetMapping, Property tableColumn, bool? isNull, string conditionValue) { CommandValidation.ValidateAssociationSetMapping(associationSetMapping); CommandValidation.ValidateTableColumn(tableColumn); _associationSetMapping = associationSetMapping; _tableColumn = tableColumn; _isNull = isNull; _conditionValue = conditionValue; }
/// <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 static AssociationIdentity CreateAssociationIdentity(AssociationSetMapping asm) { var sSideEntitySet = asm.StoreEntitySet.Target as StorageEntitySet; if (null == sSideEntitySet) { // a null sSideEntitySet indicates an unresolved AssociationSetMapping // we treat this as equivalent to the AssociationSet being unmapped return null; } var assocId = new AssociationIdentityForAssociationSetMapping(); assocId._assocTable = DatabaseObject.CreateFromEntitySet(sSideEntitySet); foreach (var endProp in asm.EndProperties()) { var assocEndId = new AssociationEndIdentity(endProp); assocId.AddAssociationEndIdentity(assocEndId); } return assocId; }
protected override void InvokeInternal(CommandProcessorContext cpc) { // if we don't have an ECM yet, go create one if (EntityContainerMapping == null) { var createECM = new CreateEntityContainerMappingCommand(AssociationSet.Artifact); CommandProcessor.InvokeSingleCommand(cpc, createECM); EntityContainerMapping = createECM.EntityContainerMapping; } Debug.Assert(EntityContainerMapping != null, "EntityContainerMapping should not be null"); if (EntityContainerMapping == null) { throw new CannotLocateParentItemException(); } // create the ETM var asm = new AssociationSetMapping(EntityContainerMapping, null); asm.Name.SetRefName(AssociationSet); asm.TypeName.SetRefName(Association); asm.StoreEntitySet.SetRefName(StorageEntitySet); EntityContainerMapping.AddAssociationSetMapping(asm); XmlModelHelper.NormalizeAndResolve(asm); Debug.Assert(asm.Name.Target != null, "Could not resolve association set reference"); Debug.Assert(asm.TypeName.Target != null, "Could not resolve association type reference"); Debug.Assert(asm.StoreEntitySet.Target != null, "Could not resolve table reference"); var assoc = asm.TypeName.Target; Debug.Assert(assoc != null, "Could not resolve association reference"); if (assoc != null) { InferReferentialConstraints.AddRule(cpc, assoc); } _created = asm; }
internal void AddAssociationSetMapping(AssociationSetMapping asm) { _associationSetMappings.Add(asm); }
/// <summary> /// Creates an EndProperty and then creates the ScalarProperty in that End. /// </summary> /// <param name="associationSetMapping"></param> /// <param name="associationSetEnd"></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> internal CreateEndScalarPropertyCommand( AssociationSetMapping associationSetMapping, AssociationSetEnd associationSetEnd, Property entityProperty, Property tableColumn) : this(associationSetMapping, associationSetEnd, entityProperty, tableColumn, true) { }
internal CreateEndPropertyCommand(AssociationSetMapping associationSetMapping, AssociationSetEnd associationSetEnd) : base(PrereqId) { AssociationSetMapping = associationSetMapping; AssociationSetEnd = associationSetEnd; }
internal static void ValidateAssociationSetMapping(AssociationSetMapping asm) { ValidateEFElement(asm); }
/// <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 EnforceAssociationSetMappingRules(CommandProcessorContext cpc, AssociationSetMapping associationSetMapping) { _cpc = cpc; _associationSetMapping = associationSetMapping; }
internal static void AddRule(CommandProcessorContext cpc, AssociationSetMapping associationSetMapping) { Debug.Assert(associationSetMapping != null, "associationSetMapping should not be null"); IIntegrityCheck check = new EnforceAssociationSetMappingRules(cpc, associationSetMapping); cpc.AddIntegrityCheck(check); }
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; }
/// <summary> /// Creates a new AssociationSetMapping in the existing EntityContainerMapping /// based on another AssociationSetMapping (asmToClone) in a different artifact. /// All the other parameters are presumed to already exist in the same artifact /// as the EntityContainerMapping. /// </summary> private AssociationSetMapping CloneAssociationSetMapping( CommandProcessorContext cpc, AssociationSetMapping asmToClone, EntityContainerMapping existingEntityContainerMapping, AssociationSet existingAssociationSet, Association existingAssociation, StorageEntitySet existingStorageEntitySet, Dictionary<EntityType, EntityType> tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact) { var createASM = new CreateAssociationSetMappingCommand( existingEntityContainerMapping, existingAssociationSet, existingAssociation, existingStorageEntitySet); CommandProcessor.InvokeSingleCommand(cpc, createASM); var asmInExistingArtifact = createASM.AssociationSetMapping; if (null == asmInExistingArtifact) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseCannotCreateAssociationSetMapping, existingAssociationSet.ToPrettyString())); } // cannot just look for an AssociationSetEnd with the same Role name in // the existing artifact as the role may have changed when the Association was // copied into the existing artifact - but we do know the ends were created in // the same order - so simply match them up var existingAssocSetEnds = existingAssociationSet.AssociationSetEnds().ToArray(); if (2 != existingAssocSetEnds.Length) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseAssociationSetMappingWrongNumberAssociationSetEnds, existingAssociationSet.ToPrettyString(), existingAssocSetEnds.Length)); } var endsToClone = asmToClone.EndProperties().ToArray(); if (2 != endsToClone.Length) { throw new UpdateModelFromDatabaseException( string.Format( CultureInfo.CurrentCulture, Resources.UpdateFromDatabaseAssociationSetMappingWrongNumberAssociationSetEnds, existingAssociationSet.ToPrettyString(), existingAssocSetEnds.Length)); } for (var i = 0; i < 2; i++) { var aseInExistingArtifact = existingAssocSetEnds[i]; var endToClone = endsToClone[i]; CloneEndProperty( cpc, endToClone, asmInExistingArtifact, aseInExistingArtifact, tempArtifactCEntityTypeToNewCEntityTypeInExistingArtifact); } return asmInExistingArtifact; }