internal EntityTypeMapping Clone(EntitySetMapping newEntitySetMapping) { // here we clone the entity type mapping, instead of re-parenting it // this works around an XML editor bug where re-parenting an element causes asserts // first create the new XElement var tempDoc = XDocument.Parse(XElement.ToString(SaveOptions.None), LoadOptions.None); var newetmXElement = tempDoc.Root; newetmXElement.Remove(); // format the XML we just parsed Utils.FormatXML(newetmXElement, newEntitySetMapping.GetIndentLevel() + 1); // create the EntityTypeMapping & hook in it's xml. var newetm = new EntityTypeMapping(newEntitySetMapping, newetmXElement); newetm.AddXElementToParent(newetmXElement); // parse & Resolve the new EntityTypeMapping newetm.Parse(new HashSet <XName>()); XmlModelHelper.NormalizeAndResolve(newetm); // add it to new EntitySetMapping newEntitySetMapping.AddEntityTypeMapping(newetm); return(newetm); }
protected override void DoParse(ICollection <XName> unprocessedElements) { // call base DoParse first base.DoParse(unprocessedElements); // now see if this has an attribute called "TypeName" if (GetAttributeValue(EntityTypeMapping.AttributeTypeName) != null) { if (_entityTypeMappings.Count == 0) { // TypeName attribute and no EntityTypeMapping children. Create a "ghost-node". var etm = new EntityTypeMapping(this, XElement); _entityTypeMappings.Add(etm); etm.Parse(unprocessedElements); // Add an error - we don't want to support this syntax in the designer. var msg = String.Format( CultureInfo.CurrentCulture, Resources.ModelParse_GhostNodeNotSupportedByDesigner, EntityTypeMapping.AttributeTypeName, ElementName); Artifact.AddParseErrorForObject(this, msg, ErrorCodes.ModelParse_GhostNodeNotSupportedByDesigner); } else { // TypeName attribute and EntityTypeMapping children. These are mutually exclusive. var msg = String.Format( CultureInfo.CurrentCulture, Resources.ModelParse_MutuallyExclusiveAttributeAndChildElement, EntityTypeMapping.AttributeTypeName, EntityTypeMapping.ElementName); Artifact.AddParseErrorForObject(this, msg, ErrorCodes.ModelParse_MutuallyExclusiveAttributeAndChildElement); } } }
/// <summary> /// Creates a MappingFragment for the passed in StorageEntitySet in the passed in ETM. /// </summary> /// <param name="entityTypeMapping">This must a valid EntityTypeMapping.</param> /// <param name="entitySet">This must be a valid StorageEntitySet.</param> internal CreateMappingFragmentCommand(EntityTypeMapping entityTypeMapping, StorageEntitySet storageEntitySet) { CommandValidation.ValidateEntityTypeMapping(entityTypeMapping); CommandValidation.ValidateStorageEntitySet(storageEntitySet); ConceptualEntityType = entityTypeMapping.FirstBoundConceptualEntityType; _entityTypeMappingKind = entityTypeMapping.Kind; _entityTypeMapping = entityTypeMapping; StorageEntitySet = storageEntitySet; }
/// <summary> /// Create MappingFragment for the passed in ConceptualEntityType and StoreEntityType, and inside the /// ETM based on the passed in kind. /// </summary> /// <param name="conceptualEntityType">This must be a valid EntityType from the C-Model.</param> /// <param name="storeEntityType">This must be a valid EntityType from the S-Model.</param> /// <param name="kind">Specify whether this should be put in an IsTypeOf or Default ETM</param> internal CreateMappingFragmentCommand(EntityType conceptualEntityType, EntityType storeEntityType, EntityTypeMappingKind kind) { CommandValidation.ValidateStorageEntityType(storeEntityType); CommandValidation.ValidateConceptualEntityType(conceptualEntityType); ConceptualEntityType = conceptualEntityType; _entityTypeMappingKind = kind; _entityTypeMapping = null; StorageEntitySet = storeEntityType.EntitySet as StorageEntitySet; CommandValidation.ValidateStorageEntitySet(StorageEntitySet); }
protected override void InvokeInternal(CommandProcessorContext cpc) { // make sure that there isn't an ETM of this kind already var entityTypeMapping = ModelHelper.FindEntityTypeMapping(cpc, _entityType, _kind, false); Debug.Assert(entityTypeMapping == null, "We are calling CreateEntityTypeMappingCommand and there is already one of this Kind"); if (entityTypeMapping != null) { _created = entityTypeMapping; return; } // see if we can get the EntitySetMapping for our entity (if we weren't passed it) if (_entitySetMapping == null) { var ces = _entityType.EntitySet as ConceptualEntitySet; Debug.Assert(ces != null, "_entityType.EntitySet should be a ConceptualEntitySet"); // find the EntitySetMapping for this type (V1 assumption is that there is only ESM per ES) EntitySetMapping esm = null; foreach (var depMapping in ces.GetAntiDependenciesOfType<EntitySetMapping>()) { esm = depMapping; break; } _entitySetMapping = esm; } // if we still don't have an ESM, create one if (_entitySetMapping == null) { var cmd = new CreateEntitySetMappingCommand( _entityType.Artifact.MappingModel().FirstEntityContainerMapping, _entityType.EntitySet as ConceptualEntitySet); CommandProcessor.InvokeSingleCommand(cpc, cmd); _entitySetMapping = cmd.EntitySetMapping; } Debug.Assert( _entitySetMapping != null, "_entitySetMapping should not be null - we have been unable to find or create an EntitySetMapping"); // create the ETM var etm = new EntityTypeMapping(_entitySetMapping, null, _kind); etm.TypeName.SetRefName(_entityType); _entitySetMapping.AddEntityTypeMapping(etm); XmlModelHelper.NormalizeAndResolve(etm); _created = etm; }
/// <summary> /// Adds the passed in EntityTypeMapping to the internal model (this EntitySetMapping becomes its parent) /// and also to the XLinq tree. /// </summary> /// <param name="etm"></param> internal void AddEntityTypeMapping(EntityTypeMapping etm) { Debug.Assert( etm.Parent == this, "unexpected condition. You are trying to move an EntityTypeMapping between parents. This is not valid. Use EntityTypeMapping's Clone() method."); _entityTypeMappings.Add(etm); Debug.Assert( etm.Parent != null && etm.Parent.XContainer != null, "The new parent for this EntityTypeMapping does not have a valid XLinq node"); if (etm.Parent != null && etm.Parent.XContainer != null && etm.Parent.XContainer != etm.XElement.Parent) { Debug.Fail("this entity type mapping already has a Parent. This is not valid. Use EntityTypeMapping's Clone() method."); } }
// an example use of an alias in a typename // // <Alias cdm:Key="CNorthwind" cdm:Value="Test.Simple.Model" /> // ... // <EntityTypeMapping cdm:TypeName="CNorthwind.CCategory"> // ... // // we need to resolve CNorthwind.CCategory to Test.Simple.Model.CCategory so we // can look it up in the symbol table internal static NormalizedName NameNormalizer(EFElement parent, string refName) { Debug.Assert(parent != null, "parent should not be null"); if (refName == null) { return(null); } // go get the needed parent objects var parentItem = parent; Debug.Assert(parentItem != null, "parent should not be an EFElement"); refName = refName.Trim(); refName = EntityTypeMapping.StripOffIsTypeOf(refName); return(EFNormalizableItemDefaults.DefaultNameNormalizerForMSL(parentItem, refName)); }
internal override bool ParseSingleElement(ICollection <XName> unprocessedElements, XElement elem) { if (elem.Name.LocalName == EntityTypeMapping.ElementName) { var etm = new EntityTypeMapping(this, elem); _entityTypeMappings.Add(etm); etm.Parse(unprocessedElements); } else if (elem.Name.LocalName == QueryView.ElementName) { var qv = new QueryView(this, elem); qv.Parse(unprocessedElements); _queryViews.Add(qv); } else { return(base.ParseSingleElement(unprocessedElements, elem)); } return(true); }
/// <summary> /// Normalize a refName where the refName is a child of a EntityTypeMapping /// <param name="etm"></param> /// <param name="fae"></param> /// <param name="parent"></param> /// <param name="refName"></param> /// <returns></returns> internal static NormalizedName NormalizePropertyNameRelativeToEntityTypeMapping( EntityTypeMapping etm, EFElement parent, string refName) { NormalizedName nn = null; if (etm != null && etm.TypeName.Status == (int)BindingStatus.Known) { // walk up until we find our EntityTypeMapping, then we can walk over to the EntityType(s) // that should contain this property name foreach (var binding in etm.TypeName.Bindings) { if (binding.Status == BindingStatus.Known) { var cet = binding.Target as ConceptualEntityType; Debug.Assert(cet != null, "EntityType is not EntityTypeMapping"); // for each entity type in the list, look to see it contains the property // if not, then check its parent var typesToCheck = new List <ConceptualEntityType>(); typesToCheck.Add(cet); typesToCheck.AddRange(cet.ResolvableBaseTypes); foreach (EntityType entityType in typesToCheck) { var entityTypeSymbol = entityType.NormalizedName; var symbol = new Symbol(entityTypeSymbol, refName); var artifactSet = parent.Artifact.ModelManager.GetArtifactSet(parent.Artifact.Uri); var item = artifactSet.LookupSymbol(symbol); if (item != null) { nn = new NormalizedName(symbol, null, null, refName); } } } } } return(nn); }
protected override void Init() { base.Init(); _isTypeOfs = new List <bool>(); if (RefName != null) { var typeNames = RefName.Split(_delimiter); foreach (var typeName in typeNames) { if (EntityTypeMapping.UsesIsTypeOf(typeName)) { _isTypeOfs.Add(true); } else { _isTypeOfs.Add(false); } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { // see if we have the ETM we need, if not create it if (_entityTypeMapping == null) { _entityTypeMapping = ModelHelper.FindEntityTypeMapping(cpc, ConceptualEntityType, _entityTypeMappingKind, true); } // make sure it was created Debug.Assert(_entityTypeMapping != null, "We should have created an EntityTypeMapping if needed, it is still null."); if (_entityTypeMapping == null) { throw new CannotLocateParentItemException(); } _createdMappingFragment = new MappingFragment(_entityTypeMapping, null); _createdMappingFragment.StoreEntitySet.SetRefName(StorageEntitySet); _entityTypeMapping.AddMappingFragment(_createdMappingFragment); XmlModelHelper.NormalizeAndResolve(_createdMappingFragment); EnforceEntitySetMappingRules.AddRule(cpc, _entityTypeMapping.EntitySetMapping); }
private static bool CommonEntityTypeMappingRules(EntityTypeMapping etm, ref string errorMessage) { // 3. make sure that we don't have any C-side conditions foreach (var frag in etm.MappingFragments()) { foreach (var cond in frag.Conditions()) { if (cond.Name.RefName != null) { errorMessage = Resources.MappingDetails_ErrMslUnsupportedCondition; return false; } } } // 4. make sure that function mappings are in their own ETM if (etm.ModificationFunctionMapping != null) { errorMessage = Resources.MappingDetails_ErrMslFunctionMappingsShouldBeSeparate; return false; } // 7. ensure that ETMs only have one MappingFragment for a given table var mappedStorageEntitySets = new HashSet<EntitySet>(); foreach (var fragment in etm.MappingFragments()) { if (fragment.StoreEntitySet.Target != null) { if (mappedStorageEntitySets.Contains(fragment.StoreEntitySet.Target)) { errorMessage = Resources.MappingDetails_ErrMslTooManyFragments; return false; } else { mappedStorageEntitySets.Add(fragment.StoreEntitySet.Target); } } } return true; }
/// <summary> /// Deletes the passed in EntityTypeMapping /// </summary> /// <param name="etm"></param> internal DeleteEntityTypeMappingCommand(EntityTypeMapping etm) : base(etm) { CommandValidation.ValidateEntityTypeMapping(etm); }
internal static void ValidateEntityTypeMapping(EntityTypeMapping etm) { ValidateEFElement(etm); Debug.Assert( etm.EntitySetMapping != null, "The passed in EntityTypeMapping has a null parent or is not a child of an EntitySetMapping"); }
internal override bool ParseSingleElement(ICollection<XName> unprocessedElements, XElement elem) { if (elem.Name.LocalName == EntityTypeMapping.ElementName) { var etm = new EntityTypeMapping(this, elem); _entityTypeMappings.Add(etm); etm.Parse(unprocessedElements); } else if (elem.Name.LocalName == QueryView.ElementName) { var qv = new QueryView(this, elem); qv.Parse(unprocessedElements); _queryViews.Add(qv); } else { return base.ParseSingleElement(unprocessedElements, elem); } return true; }
protected override void DoParse(ICollection<XName> unprocessedElements) { // call base DoParse first base.DoParse(unprocessedElements); // now see if this has an attribute called "TypeName" if (GetAttributeValue(EntityTypeMapping.AttributeTypeName) != null) { if (_entityTypeMappings.Count == 0) { // TypeName attribute and no EntityTypeMapping children. Create a "ghost-node". var etm = new EntityTypeMapping(this, XElement); _entityTypeMappings.Add(etm); etm.Parse(unprocessedElements); // Add an error - we don't want to support this syntax in the designer. var msg = String.Format( CultureInfo.CurrentCulture, Resources.ModelParse_GhostNodeNotSupportedByDesigner, EntityTypeMapping.AttributeTypeName, ElementName); Artifact.AddParseErrorForObject(this, msg, ErrorCodes.ModelParse_GhostNodeNotSupportedByDesigner); } else { // TypeName attribute and EntityTypeMapping children. These are mutually exclusive. var msg = String.Format( CultureInfo.CurrentCulture, Resources.ModelParse_MutuallyExclusiveAttributeAndChildElement, EntityTypeMapping.AttributeTypeName, EntityTypeMapping.ElementName); Artifact.AddParseErrorForObject(this, msg, ErrorCodes.ModelParse_MutuallyExclusiveAttributeAndChildElement); } } }
private static void GatherConditionsForEntityTypeMapping(EntityInfo info, EntityTypeMapping etm) { foreach (var frag in etm.MappingFragments()) { Debug.Assert(frag.StoreEntitySet.Target != null, "Found a MappingFragment with an unknown StoreEntitySet binding"); Debug.Assert( frag.StoreEntitySet.Target.EntityType.Target != null, "Found an S-Side entity set with an unknown entity binding"); if (frag.StoreEntitySet.Target != null && frag.StoreEntitySet.Target.EntityType.Target != null && info.HasTable(frag.StoreEntitySet.Target.EntityType.Target) == false) { var table = frag.StoreEntitySet.Target.EntityType.Target; var ti = new TableInfo(table); ti.EntityTypeMappingKind = etm.Kind; info.Tables.Add(table, ti); } foreach (var cond in frag.Conditions()) { info.Conditions.Add(cond); } } }
private static void GatherScalarsForEntityTypeMapping(EntityInfo info, EntityTypeMapping etm) { foreach (var frag in etm.MappingFragments()) { Debug.Assert(frag.StoreEntitySet.Target != null, "frag.StoreEntitySet.Target should not be null"); Debug.Assert( frag.StoreEntitySet.Target.EntityType.Target != null, "frag.StoreEntitySet.Target.EntityType.Target should not be null"); if (frag.StoreEntitySet.Target != null && frag.StoreEntitySet.Target.EntityType.Target != null && info.HasTable(frag.StoreEntitySet.Target.EntityType.Target) == false) { var table = frag.StoreEntitySet.Target.EntityType.Target; var ti = new TableInfo(table); ti.EntityTypeMappingKind = etm.Kind; info.Tables.Add(table, ti); } foreach (var sp in frag.ScalarProperties()) { if (info.KeyProperties.Contains(sp.Name.Target)) { info.KeyScalars.Add(sp); } else { info.NonKeyScalars.Add(sp); } } foreach (var cp in frag.ComplexProperties()) { GatherScalarsFromComplexProperty(info, cp); } } }
private static MappingFragment FindMappingFragment(EntityTypeMapping etm, EntityType table) { foreach (var fragment in etm.MappingFragments()) { if (fragment.StoreEntitySet.Target == table.EntitySet) { return fragment; } } return null; }
/// <summary> /// Creates a new EntityTypeMapping in the existing EntitySetMapping /// based on another EntityTypeMapping (etmToClone) in a different artifact. /// All the other parameters are presumed to already exist in the same artifact /// as the EntitySetMapping. /// </summary> internal static EntityTypeMapping CloneEntityTypeMapping( CommandProcessorContext cpc, EntityTypeMapping etmToClone, EntitySetMapping existingEntitySetMapping, ConceptualEntityType existingEntityType, EntityTypeMappingKind kind) { var createETM = new CreateEntityTypeMappingCommand(existingEntitySetMapping, existingEntityType, kind); var cp = new CommandProcessor(cpc, createETM); cp.Invoke(); var etm = createETM.EntityTypeMapping; foreach (var mappingFragment in etmToClone.MappingFragments()) { var sesToClone = mappingFragment.StoreEntitySet.Target as StorageEntitySet; var ses = existingEntitySetMapping.EntityContainerMapping.Artifact. StorageModel().FirstEntityContainer.GetFirstNamedChildByLocalName(sesToClone.LocalName.Value) as StorageEntitySet; CreateMappingFragmentCommand.CloneMappingFragment(cpc, mappingFragment, etm, ses); } return etm; }
internal EntityTypeMapping Clone(EntitySetMapping newEntitySetMapping) { // here we clone the entity type mapping, instead of re-parenting it // this works around an XML editor bug where re-parenting an element causes asserts // first create the new XElement var tempDoc = XDocument.Parse(XElement.ToString(SaveOptions.None), LoadOptions.None); var newetmXElement = tempDoc.Root; newetmXElement.Remove(); // format the XML we just parsed Utils.FormatXML(newetmXElement, newEntitySetMapping.GetIndentLevel() + 1); // create the EntityTypeMapping & hook in it's xml. var newetm = new EntityTypeMapping(newEntitySetMapping, newetmXElement); newetm.AddXElementToParent(newetmXElement); // parse & Resolve the new EntityTypeMapping newetm.Parse(new HashSet<XName>()); XmlModelHelper.NormalizeAndResolve(newetm); // add it to new EntitySetMapping newEntitySetMapping.AddEntityTypeMapping(newetm); return newetm; }
/// <summary> /// Creates a new MappingFragment in the existing EntityTypeMapping /// based on another MappingFragment (fragToClone) in a different artifact. /// All the other parameters are presumed to already exist in the same artifact /// as the EntityTypeMapping. /// </summary> internal static MappingFragment CloneMappingFragment( CommandProcessorContext cpc, MappingFragment fragToClone, EntityTypeMapping existingEntityTypeMapping, StorageEntitySet existingEntitySet) { var createFragmentCommand = new CreateMappingFragmentCommand(existingEntityTypeMapping, existingEntitySet); var cp = new CommandProcessor(cpc, createFragmentCommand); cp.Invoke(); var frag = createFragmentCommand.MappingFragment; Debug.Assert(frag != null, "Could not locate or create the required mapping fragment"); if (frag != null) { foreach (var sp in fragToClone.ScalarProperties()) { Property entityProperty = null; if (sp.Name != null && sp.Name.Target != null && sp.Name.Target.LocalName != null && sp.Name.Target.LocalName.Value != null) { entityProperty = ModelHelper.FindPropertyForEntityTypeMapping( existingEntityTypeMapping, sp.Name.Target.LocalName.Value); Debug.Assert( entityProperty != null, "Cannot find Property with name " + sp.Name.Target.LocalName.Value + " for EntityTypeMapping " + existingEntityTypeMapping.ToPrettyString()); } Property tableColumn = null; if (frag.StoreEntitySet != null && frag.StoreEntitySet.Target != null && frag.StoreEntitySet.Target.EntityType != null && frag.StoreEntitySet.Target.EntityType.Target != null && sp.ColumnName != null && sp.ColumnName.Target != null && sp.ColumnName.Target.LocalName != null && sp.ColumnName.Target.LocalName.Value != null) { tableColumn = ModelHelper.FindProperty( frag.StoreEntitySet.Target.EntityType.Target, sp.ColumnName.Target.LocalName.Value); Debug.Assert( tableColumn != null, "Cannot find Property with name " + sp.ColumnName.Target.LocalName.Value + " for EntityType " + frag.StoreEntitySet.Target.EntityType.Target.ToPrettyString()); } if (entityProperty != null && tableColumn != null) { var createScalarCommand = new CreateFragmentScalarPropertyCommand(frag, entityProperty, tableColumn); var cp2 = new CommandProcessor(cpc, createScalarCommand); cp2.Invoke(); } } } return frag; }
internal ModificationFunctionMapping(EntityTypeMapping parent, XElement element) : base(parent, element) { }
private void ProcessMappingFragments(EntityInfo info, EntityTypeMapping etm) { // process each relationship between the type and a table foreach (var table in info.Tables.Keys) { var tableInfo = info.Tables[table]; // find or create the mapping fragment var frag = FindMappingFragment(etm, table); if (tableInfo.UsesEntityTypeMappingKind(etm.Kind)) { if (frag == null) { var cmd = new CreateMappingFragmentCommand(etm, table.EntitySet as StorageEntitySet); CommandProcessor.InvokeSingleCommand(_cpc, cmd); frag = cmd.MappingFragment; } Debug.Assert(frag != null, "Could not locate or create the required MappingFragment"); ProcessMappingFragment(info, table, frag); } else { // don't need it, remove it if we have one if (frag != null) { AddToDeleteList(frag); } } } }
/// <summary> /// Normalize a refName where the refName is a child of a EntityTypeMapping /// <param name="etm"></param> /// <param name="fae"></param> /// <param name="parent"></param> /// <param name="refName"></param> /// <returns></returns> internal static NormalizedName NormalizePropertyNameRelativeToEntityTypeMapping( EntityTypeMapping etm, EFElement parent, string refName) { NormalizedName nn = null; if (etm != null && etm.TypeName.Status == (int)BindingStatus.Known) { // walk up until we find our EntityTypeMapping, then we can walk over to the EntityType(s) // that should contain this property name foreach (var binding in etm.TypeName.Bindings) { if (binding.Status == BindingStatus.Known) { var cet = binding.Target as ConceptualEntityType; Debug.Assert(cet != null, "EntityType is not EntityTypeMapping"); // for each entity type in the list, look to see it contains the property // if not, then check its parent var typesToCheck = new List<ConceptualEntityType>(); typesToCheck.Add(cet); typesToCheck.AddRange(cet.ResolvableBaseTypes); foreach (EntityType entityType in typesToCheck) { var entityTypeSymbol = entityType.NormalizedName; var symbol = new Symbol(entityTypeSymbol, refName); var artifactSet = parent.Artifact.ModelManager.GetArtifactSet(parent.Artifact.Uri); var item = artifactSet.LookupSymbol(symbol); if (item != null) { nn = new NormalizedName(symbol, null, null, refName); } } } } } return nn; }