/// <summary> /// This method lets you change whether an Entity is abstract or not. /// </summary> /// <param name="entityType">Must point to a valid C-Side entity</param> internal ChangeEntityTypeAbstractCommand(ConceptualEntityType entityType, bool setAbstract) { CommandValidation.ValidateConceptualEntityType(entityType); EntityType = entityType; SetAbstract = setAbstract; }
internal CreateConceptualAssociationCommand( string name, ConceptualEntityType end1Entity, string end1Multiplicity, string end1NavigationProperty, ConceptualEntityType end2Entity, string end2Multiplicity, string end2NavigationProperty, bool uniquifyNames, bool createForeignKeyProperties) : base(PrereqId) { ValidateString(name); CommandValidation.ValidateConceptualEntityType(end1Entity); ValidateString(end1Multiplicity); CommandValidation.ValidateConceptualEntityType(end2Entity); ValidateString(end2Multiplicity); Name = name; End1Entity = end1Entity; End1Multiplicity = end1Multiplicity; NavigationPropertyInEnd1Entity = end1NavigationProperty; End2Entity = end2Entity; End2Multiplicity = end2Multiplicity; NavigationPropertyInEnd2Entity = end2NavigationProperty; UniquifyNames = uniquifyNames; ShouldCreateForeignKeyProperties = createForeignKeyProperties; }
internal NewInheritanceDialog(ConceptualEntityType baseType, IEnumerable <ConceptualEntityType> entityTypes) { InitializeComponent(); // Set the default font to VS shell font. var vsFont = VSHelpers.GetVSFont(Services.ServiceProvider); if (vsFont != null) { Font = vsFont; } _entityTypes = new SortedSet <ConceptualEntityType>(new EFNameableItemComparer()); foreach (var et in entityTypes) { _entityTypes.Add(et); } baseEntityComboBox.Items.AddRange(_entityTypes.ToArray()); if (baseType != null) { baseEntityComboBox.SelectedItem = baseType; } CheckOkButtonEnabled(); cancelButton.BackColor = SystemColors.Control; cancelButton.ForeColor = SystemColors.ControlText; okButton.BackColor = SystemColors.Control; okButton.ForeColor = SystemColors.ControlText; }
internal ConceptualEntityType FindClosestAncestorTypeThatMapsToDbObject(ConceptualEntityType et, DatabaseObject dbObj) { Debug.Assert( null != _cEntityTypeNameToEntityTypeIdentity, "requires that _cEntityTypeToEntityTypeIdentity " + "is initialized for GetEntityTypeIdentityForEntityType call"); if (null == et) { Debug.Fail("Null EntityType"); return(null); } var baseType = et; while ((baseType = baseType.BaseType.Target) != null) { var baseTypeId = GetEntityTypeIdentityForEntityType(baseType); if (null != baseTypeId) { foreach (var baseTypeTableOrView in baseTypeId.TablesAndViews) { if (dbObj.Equals(baseTypeTableOrView)) { return(baseType); } } } } return(null); }
/// <summary> /// Creates an EntityTypeMapping for the passed in type and kind. If an ETM of the kind doesn't exist, /// then it creates it. /// </summary> /// <param name="entityType"></param> /// <param name="kind"></param> internal CreateEntityTypeMappingCommand(ConceptualEntityType entityType, EntityTypeMappingKind kind) { CommandValidation.ValidateConceptualEntityType(entityType); _entityType = entityType; _kind = kind; }
private static Property CreateConceptualProperty(ConceptualEntityType parentEntity, string name, string type, InsertPropertyPosition insertPosition) { var property = new ConceptualProperty(parentEntity, null, insertPosition); property.LocalName.Value = name; property.ChangePropertyType(type); return(property); }
internal static void AddRule(CommandProcessorContext cpc, ConceptualEntityType element) { if (element != null) { IIntegrityCheck check = new PropagateViewKeysToStorageModel(cpc, element); cpc.AddIntegrityCheck(check); } }
/// <summary> /// Creates an inheritance so that 'baseType' becomes the base type of the new entity being /// created by the CreateEntityTypeCommand. /// </summary> /// <param name="prereqCommand">Must be non-null</param> /// <param name="baseType">Must be non-null and a c-space entity</param> internal CreateInheritanceCommand(CreateEntityTypeCommand prereqCommand, ConceptualEntityType baseType) { ValidatePrereqCommand(prereqCommand); CommandValidation.ValidateConceptualEntityType(baseType); BaseType = baseType; AddPreReqCommand(prereqCommand); }
internal void CheckForUnmappedEntityType(ConceptualEntityType et) { if (!et.IsAbstract) { var severity = ValidationHelper.IsStorageModelEmpty(et.Artifact) ? ErrorInfo.Severity.WARNING : ErrorInfo.Severity.ERROR; var etms = et.GetAntiDependenciesOfType <EntityTypeMapping>(); if (etms.Count == 0) { // Check whether the Entity is mapped using QueryView if (et.EntitySet != null) { var ces = et.EntitySet as ConceptualEntitySet; if (ces != null && ces.EntitySetMapping != null && ces.EntitySetMapping.HasQueryViewElement) { return; } } var msg = String.Format( CultureInfo.CurrentCulture, Resources.EscherValidation_UnmappedEntityType, et.LocalName.Value); ArtifactSet.AddError( new ErrorInfo(severity, msg, et, ErrorCodes.ESCHER_VALIDATOR_UNMAPPED_ENTITY_TYPE, ErrorClass.Escher_MSL)); return; } // entity type is mapped, so check for unmapped properties foreach (var p in et.Properties()) { var ccp = p as ComplexConceptualProperty; if (ccp == null) { var sps = p.GetAntiDependenciesOfType <ScalarProperty>(); if (sps.Count == 0) { var msg = String.Format( CultureInfo.CurrentCulture, Resources.EscherValidation_UnmappedProperty, p.LocalName.Value); ArtifactSet.AddError( new ErrorInfo(severity, msg, p, ErrorCodes.ESCHER_VALIDATOR_UNMAPPED_PROPERTY, ErrorClass.Escher_MSL)); } } else { var complexType = ccp.ComplexType.Target; if (complexType != null && ModelHelper.ContainsCircularComplexTypeDefinition(complexType) == false) { CheckForUnmappedComplexProperty(ccp, ccp, ccp.LocalName.Value); } } } } }
internal static Association CreateAssociationAndAssociationSetWithDefaultNames( CommandProcessorContext cpc, ConceptualEntityType end1Entity, ConceptualEntityType end2Entity) { var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // the model that we want to add the association to var model = artifact.ConceptualModel(); if (model == null) { throw new CannotLocateParentItemException(); } // Should have discovered the association name through the behavior service. Going back to default var associationName = ModelHelper.GetUniqueName( typeof(Association), model, end1Entity.LocalName.Value + end2Entity.LocalName.Value); // pluralization service is based on English only for Dev10 IPluralizationService pluralizationService = null; var pluralize = ModelHelper.GetDesignerPropertyValueFromArtifactAsBool( OptionsDesignerInfo.ElementName, OptionsDesignerInfo.AttributeEnablePluralization, OptionsDesignerInfo.EnablePluralizationDefault, artifact); if (pluralize) { pluralizationService = DependencyResolver.GetService <IPluralizationService>(); } var end1Multiplicity = ModelConstants.Multiplicity_One; var end2Multiplicity = ModelConstants.Multiplicity_Many; var proposedEnd1NavPropName = ModelHelper.ConstructProposedNavigationPropertyName( pluralizationService, end2Entity.LocalName.Value, end2Multiplicity); var end1NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName(proposedEnd1NavPropName, end1Entity); var proposedEnd2NavPropName = ModelHelper.ConstructProposedNavigationPropertyName( pluralizationService, end1Entity.LocalName.Value, end1Multiplicity); var end2NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName( proposedEnd2NavPropName, end2Entity, new HashSet <string> { end1NavigationPropertyName }); var cac = new CreateConceptualAssociationCommand( associationName, end1Entity, end1Multiplicity, end1NavigationPropertyName, end2Entity, end2Multiplicity, end2NavigationPropertyName, false, // uniquify names false); // create foreign key properties var cp = new CommandProcessor(cpc, cac); cp.Invoke(); return(cac.CreatedAssociation); }
/// <summary> /// Creates an inheritance so that 'baseType' becomes the base type of 'entityToBeDerived' /// </summary> /// <param name="entityToBeDerived">Must be non-null and a c-space entity, it cannot already be a derived type</param> /// <param name="baseType">Must be non-null and a c-space entity</param> internal CreateInheritanceCommand(ConceptualEntityType entityToBeDerived, ConceptualEntityType baseType) { CommandValidation.ValidateConceptualEntityType(entityToBeDerived); CommandValidation.ValidateConceptualEntityType(baseType); Debug.Assert(entityToBeDerived.EntityModel == baseType.EntityModel, "Inheritance only works in the same model"); EntityToBeDerived = entityToBeDerived; EntityToBeDerivedKeyProperties = entityToBeDerived.ResolvableKeys; BaseType = baseType; }
internal EntityType FindRootAncestorTypeThatMapsToDbObject(ConceptualEntityType et, DatabaseObject dbObj) { ConceptualEntityType rootAncestor = null; var nextAncestor = et; while ((nextAncestor = FindClosestAncestorTypeThatMapsToDbObject(nextAncestor, dbObj)) != null) { rootAncestor = nextAncestor; } return(rootAncestor); }
protected override void InvokeInternal(CommandProcessorContext cpc) { var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // the model that we want to add the entity to var model = ModelHelper.GetEntityModel(artifact, ModelSpaceValue); if (model == null) { throw new CannotLocateParentItemException(); } // check for uniqueness if (UniquifyName) { Name = ModelHelper.GetUniqueName(typeof(EntityType), model, Name); } else { string msg = null; if (ModelHelper.IsUniqueName(typeof(EntityType), model, Name, false, out msg) == false) { throw new CommandValidationFailedException(msg); } } // create the new item in our model EntityType entity = null; if (model.IsCSDL) { entity = new ConceptualEntityType(model as ConceptualEntityModel, null); } else { entity = new StorageEntityType(model as StorageEntityModel, null); } Debug.Assert(entity != null, "entity should not be null"); if (entity == null) { throw new ItemCreationFailureException(); } // set the name, add it to the parent item entity.LocalName.Value = Name; model.AddEntityType(entity); XmlModelHelper.NormalizeAndResolve(entity); CreatedEntityType = entity; }
// <summary> // Calls a validation method to check if this entity's MSL is editable by the designer // </summary> private bool CanEditMappingsForEntityType(ConceptualEntityType entityType) { var errorMessage = string.Empty; if (MappingViewModelHelper.CanEditMappingsForEntityType(entityType, ref errorMessage)) { return(true); } else { SetWatermarkInfo(string.Format(CultureInfo.CurrentCulture, Resources.MappingDetails_ErrMslGeneral, errorMessage)); return(false); } }
private void PropagateToStorageEntity(ConceptualEntityType entityType) { if (entityType.HasResolvableBaseType) { foreach (var key in entityType.ResolvableTopMostBaseType.ResolvableKeys) { PropagateToStorageColumn(key); } } foreach (var property in entityType.Properties()) { PropagateToStorageColumn(property); } }
/// <summary> /// This helper function creates a new entity in the conceptual model that is derived from the /// passed in entity. /// NOTE: If the cpc already has an active transaction, these changes will be in that transaction /// and the caller of this helper method must commit it to see these changes commited. /// </summary> /// <param name="cpc"></param> /// <param name="name">The name of the new, derived entity</param> /// <param name="baseType">The entity that this new type should derive from</param> /// <param name="uniquifyName">Flag whether the name should be checked for uniqueness and then changed as required</param> /// <returns>The new EntityType</returns> internal static ConceptualEntityType CreateDerivedEntityType( CommandProcessorContext cpc, string name, ConceptualEntityType baseType, bool uniquifyName) { var cet = new CreateEntityTypeCommand(name, uniquifyName); var inh = new CreateInheritanceCommand(cet, baseType); var cp = new CommandProcessor(cpc, cet, inh); cp.Invoke(); var derivedType = cet.EntityType as ConceptualEntityType; Debug.Assert(derivedType != null, "EntityType is not ConceptualEntityType"); return(derivedType); }
internal CreateNavigationPropertyCommand( string name, ConceptualEntityType entity, Association association, AssociationEnd end1, AssociationEnd end2) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (entity == null) { throw new ArgumentNullException("entity"); } Name = name; Entity = entity; Association = association; FromEnd = end1; ToEnd = end2; }
protected override void BuildNew(CommandProcessorContext cpc, string propertyName, string propertyType) { if (StorageEntityType == null || ConceptualEntityType == null) { Debug.Fail("The AssociationSetEndMappingBuilder does not have references to everything it needs"); return; } // try to find the column with this name var tableColumn = StorageEntityType.GetFirstNamedChildByLocalName(propertyName, true) as Property; if (tableColumn != null) { // now see if there is also a property with this name var entityProperty = ConceptualEntityType.GetFirstNamedChildByLocalName(propertyName) as Property; if (entityProperty == null) { // they might be trying to map a key from the base class EntityType topMostBaseType = ConceptualEntityType.ResolvableTopMostBaseType; entityProperty = topMostBaseType.GetFirstNamedChildByLocalName(propertyName) as Property; } // if we have both, create a mapping if (entityProperty != null) { CreateEndScalarPropertyCommand cmd = null; var end = AssociationSetEnd.EndProperty; if (end == null) { // we don't have an end yet, this version will create an end as well as the scalar property cmd = new CreateEndScalarPropertyCommand( AssociationSet.AssociationSetMapping, AssociationSetEnd, entityProperty, tableColumn); } else { cmd = new CreateEndScalarPropertyCommand(end, entityProperty, tableColumn); } CommandProcessor.InvokeSingleCommand(cpc, cmd); } } }
private static void GetInheritanceScalarPropsForStorageProp( Property storageProp, ConceptualEntityType etmEntityType, out ScalarProperty scalarPropMappedToCurrentEntity, out ScalarProperty nearestScalarPropMappedToAncestorEntity) { scalarPropMappedToCurrentEntity = null; nearestScalarPropMappedToAncestorEntity = null; // assign the ScalarProp which maps storageProp within ETM where the EntityType is etmEntityType (can be null) scalarPropMappedToCurrentEntity = storageProp.GetAntiDependenciesOfType <ScalarProperty>(). FirstOrDefault <ScalarProperty>(scalarProp => scalarProp.FirstBoundConceptualEntityType == etmEntityType); // assign the ScalarProp which maps storageProp within ETM for nearest ancestor of etmEntityType (can be null) foreach (var cet in etmEntityType.ResolvableBaseTypes) { nearestScalarPropMappedToAncestorEntity = storageProp.GetAntiDependenciesOfType <ScalarProperty>(). FirstOrDefault <ScalarProperty>(scalarProp => scalarProp.FirstBoundConceptualEntityType == cet); if (nearestScalarPropMappedToAncestorEntity != null) { return; } } }
/// <summary> /// Creates a new property in the passed in conceptual entity and optionally sets additional /// facets on the property. /// NOTE: If the cpc already has an active transaction, these changes will be in that transaction /// and the caller of this helper method must commit it to see these changes commited. /// </summary> /// <param name="cpc"></param> /// <param name="name">The name of the property</param> /// <param name="entityType">Must be a conceptual entity</param> /// <param name="type">The type to use for this property (cannot be empty)</param> /// <param name="nullable">Flag whether the property is nullable or not</param> /// <param name="theDefault">Optional: the default value for this property</param> /// <param name="concurrencyMode">Optional: the concurrency mode for this property</param> /// <param name="getterAccessModifier">Optional: Get access modifier.</param> /// <param name="setterAccessModifier">Optional: Set access modifier.</param> /// <returns>The new Property</returns> internal static Property CreateConceptualProperty( CommandProcessorContext cpc, string name, ConceptualEntityType entityType, string type, bool?nullable, StringOrNone theDefault, string concurrencyMode, string getterAccessModifier, string setterAccessModifier, StringOrPrimitive <UInt32> maxLength, bool?fixedLength, StringOrPrimitive <UInt32> precision, StringOrPrimitive <UInt32> scale, bool?unicode, StringOrNone collation, string storeGeneratedPattern, InsertPropertyPosition insertPosition) { CommandValidation.ValidateConceptualEntityType(entityType); var cpcd = new CreatePropertyCommand(name, entityType, type, nullable, insertPosition); var scp = new SetConceptualPropertyFacetsCommand( cpcd, theDefault, concurrencyMode, getterAccessModifier, setterAccessModifier, maxLength, DefaultableValueBoolOrNone.GetFromNullableBool(fixedLength), precision, scale, DefaultableValueBoolOrNone.GetFromNullableBool(unicode), collation); var scpac = new SetConceptualPropertyAnnotationsCommand(cpcd, storeGeneratedPattern); var cp = new CommandProcessor(cpc, cpcd, scp, scpac); cp.Invoke(); return(cpcd.CreatedProperty); }
internal static NavigationProperty CreateDefaultProperty(CommandProcessorContext cpc, string name, ConceptualEntityType entity) { if (cpc == null) { throw new ArgumentNullException("cpc"); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (entity == null) { throw new ArgumentNullException("entity"); } var cpcd = new CreateNavigationPropertyCommand(name, entity, null, null, null); var cp = new CommandProcessor(cpc, cpcd); cp.Invoke(); return cpcd.NavigationProperty; }
internal static bool SetBaseEntityType( CommandProcessorContext cpc, ConceptualEntityType derivedEntity, ConceptualEntityType baseEntity) { if (ModelHelper.CheckForCircularInheritance(derivedEntity, baseEntity)) { var message = String.Format( CultureInfo.CurrentCulture, Resources.Error_CircularInheritanceAborted, derivedEntity.LocalName.Value, baseEntity.LocalName.Value); VsUtils.ShowErrorDialog(message); return(false); } var cp = new CommandProcessor(cpc); if (derivedEntity.BaseType.Target != null) { // CreateInheritanceCommand works only for entities that don't have base type set // so we need to remove base type first in this case cp.EnqueueCommand(new DeleteInheritanceCommand(derivedEntity)); } if (baseEntity != null) { // in case the user has chosen "(None)" then we just want to delete the existing one cp.EnqueueCommand(new CreateInheritanceCommand(derivedEntity, baseEntity)); } // a quick check to be sure Debug.Assert(cp.CommandCount > 0, "Why didn't we enqueue at least one command?"); if (cp.CommandCount > 0) { cp.Invoke(); } return(true); }
internal static bool SetBaseEntityType( CommandProcessorContext cpc, ConceptualEntityType derivedEntity, ConceptualEntityType baseEntity) { if (ModelHelper.CheckForCircularInheritance(derivedEntity, baseEntity)) { var message = String.Format( CultureInfo.CurrentCulture, Resources.Error_CircularInheritanceAborted, derivedEntity.LocalName.Value, baseEntity.LocalName.Value); VsUtils.ShowErrorDialog(message); return false; } var cp = new CommandProcessor(cpc); if (derivedEntity.BaseType.Target != null) { // CreateInheritanceCommand works only for entities that don't have base type set // so we need to remove base type first in this case cp.EnqueueCommand(new DeleteInheritanceCommand(derivedEntity)); } if (baseEntity != null) { // in case the user has chosen "(None)" then we just want to delete the existing one cp.EnqueueCommand(new CreateInheritanceCommand(derivedEntity, baseEntity)); } // a quick check to be sure Debug.Assert(cp.CommandCount > 0, "Why didn't we enqueue at least one command?"); if (cp.CommandCount > 0) { cp.Invoke(); } return true; }
/// <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 void CheckForCircularInheritance(ConceptualEntityType t) { if (t != null) { var baseTypes = new HashSet <ConceptualEntityType>(); while (t != null) { if (baseTypes.Contains(t)) { var msg = String.Format( CultureInfo.CurrentCulture, Resources.EscherValidation_CircularInheritance, NameableItemsToCommaSeparatedString(baseTypes)); ArtifactSet.AddError( new ErrorInfo( ErrorInfo.Severity.ERROR, msg, t, ErrorCodes.ESCHER_VALIDATOR_CIRCULAR_INHERITANCE, ErrorClass.Escher_CSDL)); break; } baseTypes.Add(t); t = t.BaseType.Target; } } }
private static bool IsMappedUsingTph(ConceptualEntityType derivedType, out EntityType tphTable) { var baseType = derivedType.SafeBaseType; if (derivedType != null && baseType != null) { var tablesMappedToBaseType = ModelHelper.GetTablesMappedFrom(baseType); var tablesMappedToDerivedType = ModelHelper.GetTablesMappedFrom(derivedType); foreach (var tableMappedToBaseType in tablesMappedToBaseType) { if (tablesMappedToDerivedType.Contains(tableMappedToBaseType)) { tphTable = tableMappedToBaseType; return(true); } } } tphTable = null; return(false); }
internal NewInheritanceDialog(ConceptualEntityType baseType, IEnumerable<ConceptualEntityType> entityTypes) { InitializeComponent(); // Set the default font to VS shell font. var vsFont = VSHelpers.GetVSFont(Services.ServiceProvider); if (vsFont != null) { Font = vsFont; } _entityTypes = new SortedSet<ConceptualEntityType>(new EFNameableItemComparer()); foreach (var et in entityTypes) { _entityTypes.Add(et); } baseEntityComboBox.Items.AddRange(_entityTypes.ToArray()); if (baseType != null) { baseEntityComboBox.SelectedItem = baseType; } CheckOkButtonEnabled(); }
private void ProcessSelectionFromOtherWindows(Selection selection) { _lastPrimarySelection = selection.PrimarySelection; // we might be called before we are fully initialized if (_currentMappingDetailsInfo == null) { return; } if (selection.PrimarySelection != null) { var property = selection.PrimarySelection as Property; var navProp = selection.PrimarySelection as NavigationProperty; var entityTypeShape = selection.PrimarySelection as EntityTypeShape; MappingDetailsWindowContainer.SetHintColor(Color.Transparent); if (entityTypeShape != null) { MappingDetailsWindowContainer.SetHintColor(entityTypeShape.FillColor.Value); } if (_currentMappingDetailsInfo.ViewModel != null && _currentMappingDetailsInfo.ViewModel.RootNode.ModelItem.Identity == selection.PrimarySelection.Identity) { // same item we are showing, don't do anything return; } else if (_currentMappingDetailsInfo.ViewModel != null && selection.PrimarySelection.Parent != null && ((property != null && property.Parent == _currentMappingDetailsInfo.ViewModel.RootNode.ModelItem) || (navProp != null && navProp.Relationship.Target == _currentMappingDetailsInfo.ViewModel.RootNode.ModelItem)) ) { // we are selecting a child for the parent we are showing (like property and entity), don't do anything return; } else if (_currentMappingDetailsInfo.ViewModel != null && entityTypeShape != null && entityTypeShape.EntityType != null && _currentMappingDetailsInfo.ViewModel.RootNode.ModelItem == entityTypeShape.EntityType.Target) { // if the current entity type that we are showing is as same as what the shape refers, do nothing (we try to show the same thing). return; } // reset the watermark to the default (it may have been set to an error message about hand-edited MSL) SetWatermarkInfo(_defaultWatermarkInfo); // set the screen if the user selects an entity or property // if they select a property, then resolve up to parent entity // if they select an EntityTypeShape, then resolve up the referred entity. ConceptualEntityType entityType = null; if (property != null && property.EntityType != null && property.EntityType.EntityModel.IsCSDL) { entityType = property.EntityType as ConceptualEntityType; Debug.Assert(property.EntityType != null ? entityType != null : true, "EntityType is not ConceptualEntityType"); } else if (entityTypeShape != null && entityTypeShape.EntityType != null && entityTypeShape.EntityType.Target != null) { entityType = entityTypeShape.EntityType.Target as ConceptualEntityType; Debug.Assert(entityType != null, "Why does EntityTypeShape's EntityType is not ConceptualEntityType"); } else { entityType = selection.PrimarySelection as ConceptualEntityType; } if (entityType != null && CanEditMappingsForEntityType(entityType)) { // reset our view model XRef Context.Items.SetValue(new ModelToMappingModelXRef()); // if our last view was not an entity or the entity is abstract, start out in Tables mode if (_currentMappingDetailsInfo.EntityMappingMode == EntityMappingModes.None || entityType.Abstract.Value) { _currentMappingDetailsInfo.EntityMappingMode = EntityMappingModes.Tables; } // create the view model _currentMappingDetailsInfo.ViewModel = MappingViewModelHelper.CreateViewModel(Context, entityType); // show the view model in the tool window Debug.Assert( _currentMappingDetailsInfo.ViewModel != null && _currentMappingDetailsInfo.ViewModel.RootNode != null, "Failed to correctly create the mapping details ViewModel for the selected entity"); if (_currentMappingDetailsInfo.ViewModel != null && _currentMappingDetailsInfo.ViewModel.RootNode != null) { DoShowMappingDetailsForElement(_currentMappingDetailsInfo.ViewModel.RootNode.ModelItem); } // update the toolbar buttons MappingDetailsWindowContainer.UpdateToolbar(); return; } // see if user selected a navigation property, and treat the mapping view as if the user selected an association var association = GetAssociationFromLastPrimarySelection(); if (association != null && association.EntityModel.IsCSDL && CanEditMappingsForAssociation(association, false)) { SetUpAssociationDisplay(); return; } // set the screen if the user selected a FunctionImport var fi = selection.PrimarySelection as FunctionImport; if (fi != null && fi.FunctionImportMapping != null) { // only show mappings for FunctionImports that ReturnType is either EntityType or ComplexType var isReturnTypeEntityOrComplexType = fi.IsReturnTypeEntityType || fi.IsReturnTypeComplexType; if (isReturnTypeEntityOrComplexType && CanEditMappingsForFunctionImport(fi)) { // reset our view model XRef Context.Items.SetValue(new ModelToMappingModelXRef()); // set our mode to None since we aren't mapping entities _currentMappingDetailsInfo.EntityMappingMode = EntityMappingModes.None; _currentMappingDetailsInfo.ViewModel = MappingViewModelHelper.CreateViewModel(Context, fi.FunctionImportMapping); // show the view model in the tool window Debug.Assert( _currentMappingDetailsInfo.ViewModel != null && _currentMappingDetailsInfo.ViewModel.RootNode != null, "Failed to correctly create the mapping details ViewModel for the selected association"); if (_currentMappingDetailsInfo.ViewModel != null && _currentMappingDetailsInfo.ViewModel.RootNode != null) { DoShowMappingDetailsForElement(_currentMappingDetailsInfo.ViewModel.RootNode.ModelItem); } // update the toolbar buttons MappingDetailsWindowContainer.UpdateToolbar(); return; } } } // the user clicked on something other than an entity or association ClearToolWindowContents(false); // clear out our selection source _currentMappingDetailsInfo.SelectionSource = EntityMappingSelectionSource.None; }
internal static void CreateEntityTypeShapeAndConnectorsInDiagram( CommandProcessorContext cpc, Diagram diagram, ConceptualEntityType entity, bool createRelatedEntityTypeShapes) { CreateEntityTypeShapeAndConnectorsInDiagram( cpc, diagram, entity, EntityDesignerDiagramConstant.EntityTypeShapeDefaultFillColor, createRelatedEntityTypeShapes); }
internal InheritanceAdd(Inheritance inheritance, ConceptualEntityType baseEntity, ConceptualEntityType derivedEntity) { _inheritance = inheritance; _baseEntity = baseEntity; _derivedEntity = derivedEntity; }
/// <summary> /// Translate base type of a model EntityType into view Inheritance (creates an Inheritance if not yet created) /// </summary> /// <param name="viewModel"></param> /// <param name="entityType"></param> /// <returns></returns> private static Inheritance TranslateBaseType(EntityDesignerViewModel viewModel, ConceptualEntityType entityType) { if (entityType.BaseType.Status == BindingStatus.Known) { var baseType = ModelToDesignerModelXRef.GetExisting(viewModel.EditingContext, entityType.BaseType.Target, viewModel.Partition) as ViewModelEntityType; var derivedType = ModelToDesignerModelXRef.GetExisting(viewModel.EditingContext, entityType, viewModel.Partition) as ViewModelEntityType; // in Multiple diagram scenario, baseType and derivedType might not exist in the diagram. if (baseType != null && derivedType != null) { return ModelToDesignerModelXRef.GetNewOrExisting(viewModel.EditingContext, entityType.BaseType, baseType, derivedType) as Inheritance; } } return null; }
internal EntityInfo(ConceptualEntityType entityType, EntityInfo parentInfo) { EntityType = entityType; Parent = parentInfo; Parent.Children.Add(this); }
/// <summary> /// Deletes the base type from passed in entity type /// </summary> /// <param name="derivedType">Must be non-null and a c-space entity</param> internal DeleteInheritanceCommand(ConceptualEntityType derivedType) { CommandValidation.ValidateConceptualEntityType(derivedType); _derivedType = derivedType; }
internal ConceptualEntityType FindClosestAncestorTypeThatMapsToDbObject(ConceptualEntityType et, DatabaseObject dbObj) { Debug.Assert( null != _cEntityTypeNameToEntityTypeIdentity, "requires that _cEntityTypeToEntityTypeIdentity " + "is initialized for GetEntityTypeIdentityForEntityType call"); if (null == et) { Debug.Fail("Null EntityType"); return null; } var baseType = et; while ((baseType = baseType.BaseType.Target) != null) { var baseTypeId = GetEntityTypeIdentityForEntityType(baseType); if (null != baseTypeId) { foreach (var baseTypeTableOrView in baseTypeId.TablesAndViews) { if (dbObj.Equals(baseTypeTableOrView)) { return baseType; } } } } return null; }
internal static void CreateEntityTypeShapeAndConnectorsInDiagram( CommandProcessorContext cpc, Diagram diagram, ConceptualEntityType entity, Color entityTypeShapeFillColor, bool createRelatedEntityTypeShapes) { // if the entity type shape has been created, return immediately. if (entity == null || entity.GetAntiDependenciesOfType<EntityTypeShape>().Count(ets => ets.Diagram.Id == diagram.Id.Value) > 0) { return; } var createEntityTypeShapecommand = new CreateEntityTypeShapeCommand(diagram, entity, entityTypeShapeFillColor); createEntityTypeShapecommand.PostInvokeEvent += (o, eventsArgs) => { if (createEntityTypeShapecommand.EntityTypeShape != null) { var relatedEntityTypesNotInDiagram = new List<EntityType>(); var entityTypesInDiagram = new HashSet<EntityType>(diagram.EntityTypeShapes.Select(ets => ets.EntityType.Target)); // add inheritance connector if the base type exists in the diagram. if (entity.SafeBaseType != null) { if (entityTypesInDiagram.Contains(entity.SafeBaseType)) { CommandProcessor.InvokeSingleCommand(cpc, new CreateInheritanceConnectorCommand(diagram, entity)); } else { relatedEntityTypesNotInDiagram.Add(entity.SafeBaseType); } } // add the inheritance connector if the derived type exist in the diagram. foreach (var derivedEntityType in entity.ResolvableDirectDerivedTypes) { if (entityTypesInDiagram.Contains(derivedEntityType)) { CommandProcessor.InvokeSingleCommand(cpc, new CreateInheritanceConnectorCommand(diagram, derivedEntityType)); } else { relatedEntityTypesNotInDiagram.Add(derivedEntityType); } } // Find all associations which the entity type participates. var participatingAssociations = Association.GetAssociationsForEntityType(entity); foreach (var association in participatingAssociations) { var entityTypesInAssociation = association.AssociationEnds().Select(ae => ae.Type.Target).ToList(); var entityTypesNotInDiagram = entityTypesInAssociation.Except(entityTypesInDiagram).ToList(); if (entityTypesNotInDiagram.Count == 0) { CommandProcessor.InvokeSingleCommand(cpc, new CreateAssociationConnectorCommand(diagram, association)); } relatedEntityTypesNotInDiagram.AddRange(entityTypesNotInDiagram); } if (createRelatedEntityTypeShapes) { foreach (var entityType in relatedEntityTypesNotInDiagram) { // we only want to bring entity-type directly related to the entity-type, so set createRelatedEntityTypeShapes flag to false. CreateEntityTypeShapeAndConnectorsInDiagram( cpc, diagram, entityType as ConceptualEntityType, entityTypeShapeFillColor, false); } } } }; CommandProcessor.InvokeSingleCommand(cpc, createEntityTypeShapecommand); }
internal EntityInfo(ConceptualEntityType entityType) { EntityType = entityType; }
/// <summary> /// Creates a new property in the passed in conceptual entity and optionally sets additional /// facets on the property. /// NOTE: If the cpc already has an active transaction, these changes will be in that transaction /// and the caller of this helper method must commit it to see these changes commited. /// </summary> /// <param name="cpc"></param> /// <param name="name">The name of the property</param> /// <param name="entityType">Must be a conceptual entity</param> /// <param name="type">The type to use for this property (cannot be empty)</param> /// <param name="nullable">Flag whether the property is nullable or not</param> /// <param name="theDefault">Optional: the default value for this property</param> /// <param name="concurrencyMode">Optional: the concurrency mode for this property</param> /// <param name="getterAccessModifier">Optional: Get access modifier.</param> /// <param name="setterAccessModifier">Optional: Set access modifier.</param> /// <returns>The new Property</returns> internal static Property CreateConceptualProperty( CommandProcessorContext cpc, string name, ConceptualEntityType entityType, string type, bool? nullable, StringOrNone theDefault, string concurrencyMode, string getterAccessModifier, string setterAccessModifier, StringOrPrimitive<UInt32> maxLength, bool? fixedLength, StringOrPrimitive<UInt32> precision, StringOrPrimitive<UInt32> scale, bool? unicode, StringOrNone collation, string storeGeneratedPattern, InsertPropertyPosition insertPosition) { CommandValidation.ValidateConceptualEntityType(entityType); var cpcd = new CreatePropertyCommand(name, entityType, type, nullable, insertPosition); var scp = new SetConceptualPropertyFacetsCommand( cpcd, theDefault, concurrencyMode, getterAccessModifier, setterAccessModifier, maxLength, DefaultableValueBoolOrNone.GetFromNullableBool(fixedLength), precision, scale, DefaultableValueBoolOrNone.GetFromNullableBool(unicode), collation); var scpac = new SetConceptualPropertyAnnotationsCommand(cpcd, storeGeneratedPattern); var cp = new CommandProcessor(cpc, cpcd, scp, scpac); cp.Invoke(); return cpcd.CreatedProperty; }
internal static NavigationProperty CreateDefaultProperty(CommandProcessorContext cpc, string name, ConceptualEntityType entity) { if (cpc == null) { throw new ArgumentNullException("cpc"); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (entity == null) { throw new ArgumentNullException("entity"); } var cpcd = new CreateNavigationPropertyCommand(name, entity, null, null, null); var cp = new CommandProcessor(cpc, cpcd); cp.Invoke(); return(cpcd.NavigationProperty); }
/// <summary> /// Translate model EntityType into view EntityType (creates a view EntityType if not yet created) /// </summary> /// <param name="viewModel"></param> /// <param name="entityType"></param> /// <param name="processChildren"></param> /// <returns></returns> private static ViewModelEntityType TranslateEntityType(EntityDesignerViewModel viewModel, ConceptualEntityType entityType) { var viewET = ModelToDesignerModelXRef.GetNewOrExisting(viewModel.EditingContext, entityType, viewModel.Partition) as ViewModelEntityType; viewET.Name = entityType.LocalName.Value; return viewET; }
internal bool HasAncestorTypeThatMapsToDbObject(ConceptualEntityType et, DatabaseObject dbObj) { return (FindClosestAncestorTypeThatMapsToDbObject(et, dbObj) == null ? false : true); }
internal static void CreateEntityTypeShapeAndConnectorsInDiagram( CommandProcessorContext cpc, Diagram diagram, ConceptualEntityType entity, Color entityTypeShapeFillColor, bool createRelatedEntityTypeShapes) { // if the entity type shape has been created, return immediately. if (entity == null || entity.GetAntiDependenciesOfType <EntityTypeShape>().Count(ets => ets.Diagram.Id == diagram.Id.Value) > 0) { return; } var createEntityTypeShapecommand = new CreateEntityTypeShapeCommand(diagram, entity, entityTypeShapeFillColor); createEntityTypeShapecommand.PostInvokeEvent += (o, eventsArgs) => { if (createEntityTypeShapecommand.EntityTypeShape != null) { var relatedEntityTypesNotInDiagram = new List <EntityType>(); var entityTypesInDiagram = new HashSet <EntityType>(diagram.EntityTypeShapes.Select(ets => ets.EntityType.Target)); // add inheritance connector if the base type exists in the diagram. if (entity.SafeBaseType != null) { if (entityTypesInDiagram.Contains(entity.SafeBaseType)) { CommandProcessor.InvokeSingleCommand(cpc, new CreateInheritanceConnectorCommand(diagram, entity)); } else { relatedEntityTypesNotInDiagram.Add(entity.SafeBaseType); } } // add the inheritance connector if the derived type exist in the diagram. foreach (var derivedEntityType in entity.ResolvableDirectDerivedTypes) { if (entityTypesInDiagram.Contains(derivedEntityType)) { CommandProcessor.InvokeSingleCommand(cpc, new CreateInheritanceConnectorCommand(diagram, derivedEntityType)); } else { relatedEntityTypesNotInDiagram.Add(derivedEntityType); } } // Find all associations which the entity type participates. var participatingAssociations = Association.GetAssociationsForEntityType(entity); foreach (var association in participatingAssociations) { var entityTypesInAssociation = association.AssociationEnds().Select(ae => ae.Type.Target).ToList(); var entityTypesNotInDiagram = entityTypesInAssociation.Except(entityTypesInDiagram).ToList(); if (entityTypesNotInDiagram.Count == 0) { CommandProcessor.InvokeSingleCommand(cpc, new CreateAssociationConnectorCommand(diagram, association)); } relatedEntityTypesNotInDiagram.AddRange(entityTypesNotInDiagram); } if (createRelatedEntityTypeShapes) { foreach (var entityType in relatedEntityTypesNotInDiagram) { // we only want to bring entity-type directly related to the entity-type, so set createRelatedEntityTypeShapes flag to false. CreateEntityTypeShapeAndConnectorsInDiagram( cpc, diagram, entityType as ConceptualEntityType, entityTypeShapeFillColor, false); } } } }; CommandProcessor.InvokeSingleCommand(cpc, createEntityTypeShapecommand); }
internal EntityType FindRootAncestorTypeThatMapsToDbObject(ConceptualEntityType et, DatabaseObject dbObj) { ConceptualEntityType rootAncestor = null; var nextAncestor = et; while ((nextAncestor = FindClosestAncestorTypeThatMapsToDbObject(nextAncestor, dbObj)) != null) { rootAncestor = nextAncestor; } return rootAncestor; }
private static void InjectEntityTypeShapeCommand( CommandProcessorContext commandProcessorContext, HashSet<ShapeChangeInformation> shapeChangeInfoSet, Diagram diagram, ConceptualEntityType entityType, XObjectChange changeAction) { // First check to see if there is already a change in the original transaction // for the EntityTypeShape that matches the one that we're getting var shapeChangeInfoToQuery = new ShapeChangeInformation { ChangeType = changeAction, ModelEFObject = entityType, DiagramId = diagram.Id.Value }; var shapeChangeInfoExists = shapeChangeInfoSet.Contains(shapeChangeInfoToQuery); // We only want to create model diagram if the transaction is originated from this diagram. if (changeAction == XObjectChange.Add) { // We only want to inject the entity-type-shape if the transaction is originated from the passed in diagram. if (commandProcessorContext != null && commandProcessorContext.EfiTransaction != null) { var contextItem = commandProcessorContext.EfiTransaction.GetContextValue<DiagramContextItem>( EfiTransactionOriginator.TransactionOriginatorDiagramId); if (contextItem != null && contextItem.DiagramId == diagram.Id.Value) { // look in the dictionary for an 'add' to an EntityTypeShape that points to this modelobject. if (shapeChangeInfoExists == false) { var cmd = new CreateEntityTypeShapeCommand(diagram, entityType); CommandProcessor.InvokeSingleCommand(commandProcessorContext, cmd); } // We have the ability to create an EntityType and an Inheritance in one transaction, so we need // to check for it here. if (entityType.BaseType.Target != null) { InjectInheritanceConnectorCommand( commandProcessorContext, shapeChangeInfoSet, diagram, entityType.BaseType, changeAction); } } } } else if (changeAction == XObjectChange.Remove && shapeChangeInfoExists == false) { // this is happening before the transaction is taking place so we are free to look up anti-dependencies // on this delete foreach ( var entityTypeShape in entityType.GetAntiDependenciesOfType<EntityTypeShape>() .Where(ets => ets.Diagram != null && ets.Diagram.Id == diagram.Id.Value)) { if (entityTypeShape != null) { var deleteEntityTypeShapeCommand = entityTypeShape.GetDeleteCommand(); CommandProcessor.InvokeSingleCommand(commandProcessorContext, deleteEntityTypeShapeCommand); } } } }
/// <summary> /// This command eases creating EntityTypeMappings because the views can interact with entityTypes and be /// abstracted away from there being different types of ETMs. /// For every EntitySetMapping (one per Entity), there will always be one EntityTypeMapping. /// <EntityTypeMapping TypeName="Person" /> /// or /// <EntityTypeMapping TypeName="IsTypeOf(Person)" /> /// - Use the IsType when a) the table is mapped with no conditions or b) the table is /// mapped with conditions, none of which are repeated by none of its subtypes. /// - Use the Default otherwise. /// This logic is enforced by the EnforceEntitySetMappingRules integrity check. We always /// start out by creating an IsTypeOf. /// </summary> /// <param name="entityType">This must be a valid EntityType from the C-Model.</param> internal CreateEntityTypeMappingCommand(ConceptualEntityType entityType) : this(entityType, EntityTypeMappingKind.IsTypeOf) { }
private static Property CreateConceptualProperty(ConceptualEntityType parentEntity, string name, string type, InsertPropertyPosition insertPosition) { var property = new ConceptualProperty(parentEntity, null, insertPosition); property.LocalName.Value = name; property.ChangePropertyType(type); return property; }
internal static Association CreateAssociationAndAssociationSetWithDefaultNames( CommandProcessorContext cpc, ConceptualEntityType end1Entity, ConceptualEntityType end2Entity) { var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // the model that we want to add the association to var model = artifact.ConceptualModel(); if (model == null) { throw new CannotLocateParentItemException(); } // Should have discovered the association name through the behavior service. Going back to default var associationName = ModelHelper.GetUniqueName( typeof(Association), model, end1Entity.LocalName.Value + end2Entity.LocalName.Value); // pluralization service is based on English only for Dev10 IPluralizationService pluralizationService = null; var pluralize = ModelHelper.GetDesignerPropertyValueFromArtifactAsBool( OptionsDesignerInfo.ElementName, OptionsDesignerInfo.AttributeEnablePluralization, OptionsDesignerInfo.EnablePluralizationDefault, artifact); if (pluralize) { pluralizationService = DependencyResolver.GetService<IPluralizationService>(); } var end1Multiplicity = ModelConstants.Multiplicity_One; var end2Multiplicity = ModelConstants.Multiplicity_Many; var proposedEnd1NavPropName = ModelHelper.ConstructProposedNavigationPropertyName( pluralizationService, end2Entity.LocalName.Value, end2Multiplicity); var end1NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName(proposedEnd1NavPropName, end1Entity); var proposedEnd2NavPropName = ModelHelper.ConstructProposedNavigationPropertyName( pluralizationService, end1Entity.LocalName.Value, end1Multiplicity); var end2NavigationPropertyName = ModelHelper.GetUniqueConceptualPropertyName( proposedEnd2NavPropName, end2Entity, new HashSet<string> { end1NavigationPropertyName }); var cac = new CreateConceptualAssociationCommand( associationName, end1Entity, end1Multiplicity, end1NavigationPropertyName, end2Entity, end2Multiplicity, end2NavigationPropertyName, false, // uniquify names false); // create foreign key properties var cp = new CommandProcessor(cpc, cac); cp.Invoke(); return cac.CreatedAssociation; }
/// <summary> /// This helper function creates a new entity in the conceptual model that is derived from the /// passed in entity. /// NOTE: If the cpc already has an active transaction, these changes will be in that transaction /// and the caller of this helper method must commit it to see these changes commited. /// </summary> /// <param name="cpc"></param> /// <param name="name">The name of the new, derived entity</param> /// <param name="baseType">The entity that this new type should derive from</param> /// <param name="uniquifyName">Flag whether the name should be checked for uniqueness and then changed as required</param> /// <returns>The new EntityType</returns> internal static ConceptualEntityType CreateDerivedEntityType( CommandProcessorContext cpc, string name, ConceptualEntityType baseType, bool uniquifyName) { var cet = new CreateEntityTypeCommand(name, uniquifyName); var inh = new CreateInheritanceCommand(cet, baseType); var cp = new CommandProcessor(cpc, cet, inh); cp.Invoke(); var derivedType = cet.EntityType as ConceptualEntityType; Debug.Assert(derivedType != null, "EntityType is not ConceptualEntityType"); return derivedType; }
private static void GetInheritanceScalarPropsForStorageProp( Property storageProp, ConceptualEntityType etmEntityType, out ScalarProperty scalarPropMappedToCurrentEntity, out ScalarProperty nearestScalarPropMappedToAncestorEntity) { scalarPropMappedToCurrentEntity = null; nearestScalarPropMappedToAncestorEntity = null; // assign the ScalarProp which maps storageProp within ETM where the EntityType is etmEntityType (can be null) scalarPropMappedToCurrentEntity = storageProp.GetAntiDependenciesOfType<ScalarProperty>(). FirstOrDefault<ScalarProperty>(scalarProp => scalarProp.FirstBoundConceptualEntityType == etmEntityType); // assign the ScalarProp which maps storageProp within ETM for nearest ancestor of etmEntityType (can be null) foreach (var cet in etmEntityType.ResolvableBaseTypes) { nearestScalarPropMappedToAncestorEntity = storageProp.GetAntiDependenciesOfType<ScalarProperty>(). FirstOrDefault<ScalarProperty>(scalarProp => scalarProp.FirstBoundConceptualEntityType == cet); if (nearestScalarPropMappedToAncestorEntity != null) { return; } } }
internal PropagateViewKeysToStorageModel(CommandProcessorContext cpc, ConceptualEntityType entityType) { _cpc = cpc; _conceptualEntityType = entityType; }
internal static bool CanEditMappingsForEntityType(ConceptualEntityType entityType, ref string errorMessage) { // make sure that the MSL is not using Ghost Nodes if (ModelHelper.IsAntiDepPartOfGhostMappingNode<EntityTypeMapping>(entityType)) { errorMessage = Resources.MappingDetails_ErrMslUsesGhostNodes; return false; } // make sure that we have an EntitySet (or can find one) if (entityType.EntitySet == null) { errorMessage = Resources.MappingDetails_ErrMslCantFindEntitySet; return false; } // make sure that there is just one EntitySetMapping for our set var esms = entityType.EntitySet.GetAntiDependenciesOfType<EntitySetMapping>(); if (esms.Count > 1) { errorMessage = Resources.MappingDetails_ErrMslTooManyEntitySetMappings; return false; } else { foreach (var esm in esms) { if (EnsureResolvedStatus(esm, ref errorMessage) == false) { return false; } // if the EntitySetMapping contains QueryView if (esm.HasQueryViewElement) { errorMessage = Resources.MappingDetails_ErrMslEntitySetMappingHasQueryView; return false; } } } // load a collection of this entity's keys var baseMostType = entityType.ResolvableTopMostBaseType; var keys = new List<Property>(); if (baseMostType.Key != null) { foreach (var keyRef in baseMostType.Key.PropertyRefs) { if (keyRef.Name.Target != null) { keys.Add(keyRef.Name.Target); } } } // Check whether the entity type is a derived type and has keys defined. if (entityType.HasResolvableBaseType && null != entityType.Key && null != entityType.Key.PropertyRefs && entityType.Key.PropertyRefs.Count > 0) { errorMessage = Resources.MappingDetails_ErrKeyInDerivedType; return false; } // make sure that: // 1. we have at most one Default ETM, one IsTypeOf ETM, and one Function ETM // 2. that each ETM only points to a single EntityType // 3. make sure that we don't have any C-side conditions // 4. make sure that function mappings are in their own ETM // 5. make sure that we don't have both a default and an IsTypeOf ETM // Removed #5 per Bug 563490: In some hybrid TPH scenarios, this is actually valid // 6. ensure that the EntitySetMapping is hooked up to the entity's entity set // 7. ensure that ETMs only have one MappingFragment for a given table var foundDefaultETM = false; var foundIsTypeOfETM = false; var foundFunctionETM = false; foreach (var etm in entityType.GetAntiDependenciesOfType<EntityTypeMapping>()) { if (etm.Kind == EntityTypeMappingKind.Default) { // 1. we have at most one Default ETM, one IsTypeOf ETM and one Function ETM if (foundDefaultETM) { errorMessage = Resources.MappingDetails_ErrMslTooManyDefaultEtms; return false; } foundDefaultETM = true; // 3. make sure that we don't have any C-side conditions // 4. make sure that function mappings are in their own ETM // 7. ensure that ETMs only have one MappingFragment if (CommonEntityTypeMappingRules(etm, ref errorMessage) == false) { return false; } } else if (etm.Kind == EntityTypeMappingKind.IsTypeOf) { // 1. we have at most one Default ETM, one IsTypeOf ETM and one Function ETM if (foundIsTypeOfETM) { errorMessage = Resources.MappingDetails_ErrMslTooManyIsTypeOfETMs; return false; } foundIsTypeOfETM = true; // 3. make sure that we don't have any C-side conditions // 4. make sure that function mappings are in their own ETM // 7. ensure that ETMs only have one MappingFragment if (CommonEntityTypeMappingRules(etm, ref errorMessage) == false) { return false; } } else if (etm.Kind == EntityTypeMappingKind.Function) { // 1. we have at most one Default ETM, one IsTypeOf ETM and one Function ETM if (foundFunctionETM) { errorMessage = Resources.MappingDetails_ErrMslTooManyFunctionETMs; return false; } foundFunctionETM = true; // 4. make sure that function mappings are in their own ETM if (etm.MappingFragments().Count != 0) { errorMessage = Resources.MappingDetails_ErrMslFunctionMappingsShouldBeSeparate; return false; } } // 2. that each ETM only points to a single EntityType if (etm.TypeName.IsTypeOfs.Count > 1) { errorMessage = Resources.MappingDetails_ErrMslEtmRefsMultipleTypes; return false; } // 6. ensure that the EntitySetMapping is hooked up to the entity's entity set if (!(etm.EntitySetMapping.Name.Status == BindingStatus.Known && etm.EntitySetMapping.Name.Target == entityType.EntitySet)) { errorMessage = Resources.MappingDetails_ErrMslBadEntitySetMapping; return false; } } string duplicatePropertyName; if (!CheckDuplicateEntityProperty(entityType, out duplicatePropertyName)) { errorMessage = string.Format( CultureInfo.CurrentCulture, Resources.MappingDetails_ErrDupePropertyNames, entityType.LocalName.Value, duplicatePropertyName); return false; } return true; }