/// <summary> /// Creates new ComplexTypeMapping inside specified FunctionImportMapping /// </summary> /// <param name="createFunctionImportMapping"></param> /// <param name="complexType"></param> internal CreateFunctionImportTypeMappingCommand( CreateFunctionImportMappingCommand createFunctionImportMappingCmd, ComplexType complexType) : base(PrereqId) { CommandValidation.ValidateComplexType(complexType); _complexType = complexType; AddPreReqCommand(createFunctionImportMappingCmd); }
internal ChangeComplexPropertyTypeCommand(ComplexConceptualProperty property, ComplexType newType) { CommandValidation.ValidateProperty(property); CommandValidation.ValidateComplexType(newType); _property = property; _newType = newType; }
// <summary> // Use this constructor if you want to remove a ComplexType (for example currently selected) from the list // </summary> internal ComplexTypePickerDialog(ConceptualEntityModel cModel, ComplexType complexTypeToRemove) : this(cModel) { Debug.Assert(complexTypeToRemove != null, "Null ComplexType passed"); if (complexTypeToRemove != null) { complexTypesListBox.Items.Remove(complexTypeToRemove); } }
/// <summary> /// Creates new ComplexTypeMapping inside specified FunctionImportMapping /// </summary> /// <param name="functionImportMapping"></param> /// <param name="complexType"></param> internal CreateFunctionImportTypeMappingCommand(FunctionImportMapping functionImportMapping, ComplexType complexType) : base(PrereqId) { CommandValidation.ValidateFunctionImportMapping(functionImportMapping); CommandValidation.ValidateComplexType(complexType); _functionImportMapping = functionImportMapping; _complexType = complexType; }
protected override void InvokeInternal(CommandProcessorContext cpc) { // first create new ComplexType _createdComplexType = CreateComplexTypeCommand.CreateComplexTypeWithDefaultName(cpc); // add a copy of Entity properties to the ComplexType var copyCmd = new CopyPropertiesCommand(new PropertiesClipboardFormat(_properties), _createdComplexType); var propertyName = ModelHelper.GetUniqueConceptualPropertyName( ComplexConceptualProperty.DefaultComplexPropertyName, _entityType); // add a new Property of created ComplexType to the Entity var createCPCmd = new CreateComplexPropertyCommand(propertyName, _entityType, _createdComplexType); var cp = new CommandProcessor(cpc, copyCmd, createCPCmd); cp.Invoke(); _createdComplexProperty = createCPCmd.Property; // preserve mappings foreach (var property in _properties) { if (property is ComplexConceptualProperty) { var createdComplexTypeProperty = _createdComplexType.FindPropertyByLocalName(property.LocalName.Value) as ComplexConceptualProperty; Debug.Assert(createdComplexTypeProperty != null, "Copied complex property not found"); if (createdComplexTypeProperty != null) { foreach (var complexPropertyMapping in property.GetAntiDependenciesOfType<ComplexProperty>()) { PreserveComplexPropertyMapping(cpc, complexPropertyMapping, createdComplexTypeProperty); } foreach (var fcp in property.GetAntiDependenciesOfType<FunctionComplexProperty>()) { PreserveFunctionComplexPropertyMapping(cpc, fcp, createdComplexTypeProperty); } } } else { var createdComplexTypeProperty = _createdComplexType.FindPropertyByLocalName(property.LocalName.Value); Debug.Assert(createdComplexTypeProperty != null, "Copied property not found"); if (createdComplexTypeProperty != null) { // update EntityTypeMappings foreach (var scalarPropertyMapping in property.GetAntiDependenciesOfType<ScalarProperty>()) { PreserveScalarPropertyMapping(cpc, scalarPropertyMapping, createdComplexTypeProperty); } // update ModificationFunctionMappings foreach (var fsp in property.GetAntiDependenciesOfType<FunctionScalarProperty>()) { PreserveFunctionScalarPropertyMapping(cpc, fsp, createdComplexTypeProperty); } } } } }
internal ComplexTypeClipboardFormat(ComplexType complexType) : base(complexType) { if (complexType == null) { throw new ArgumentNullException("complexType"); } _name = complexType.LocalName.Value; _properties = new PropertiesClipboardFormat(complexType.Properties()); }
/// <summary> /// Creates a complex property in the passed in ComplexType. /// </summary> /// <param name="name">The name of the new property</param> /// <param name="parentComplexType">The ComplexType to create the property in</param> /// <param name="complexType">The complex type of the property</param> /// <param name="nullable">Flag whether the property is nullable or not</param> internal CreateComplexTypePropertyCommand(string name, ComplexType parentComplexType, ComplexType complexType, bool? nullable) : base(PrereqId) { ValidateString(name); CommandValidation.ValidateComplexType(parentComplexType); CommandValidation.ValidateComplexType(complexType); Name = name; ParentComplexType = parentComplexType; ComplexType = complexType; Nullable = nullable; }
protected override void InvokeInternal(CommandProcessorContext cpc) { // create copy of the ComplexType var cmd = new CreateComplexTypeCommand(_clipboardComplexType.Name, true); CommandProcessor.InvokeSingleCommand(cpc, cmd); _createdComplexType = cmd.ComplexType; // copy child properties var cmd2 = new CopyPropertiesCommand(_clipboardComplexType.Properties, _createdComplexType); CommandProcessor.InvokeSingleCommand(cpc, cmd2); AddAnnotations(_clipboardComplexType, _createdComplexType); }
/// <summary> /// Creates a ComplexProperty in the passed in entity using ComplexType as a type for it. /// The complex property will be placed in the specified insertPosition parameter. /// </summary> /// <param name="name">The name of the new property</param> /// <param name="entityType">The entity to create the property in</param> /// <param name="type">The type of the property (can be null)</param> /// <param name="insertPosition">Information where the property should be inserted to. If the parameter is null, the property will be placed as the last property of the entity.</param> internal CreateComplexPropertyCommand(string name, EntityType entityType, ComplexType type, InsertPropertyPosition insertPosition) { if (insertPosition != null) { Debug.Assert( insertPosition.InsertAtProperty != null && insertPosition.InsertAtProperty.EntityType == entityType, "Could not create complex property in the given insertPosition because insertPosition's Entity-Type is not the same as the entity-type which the property will be created in."); } ValidateString(name); CommandValidation.ValidateEntityType(entityType); Name = name; EntityType = entityType; ComplexType = type; _insertPosition = insertPosition; }
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 = artifact.ConceptualModel(); if (model == null) { throw new CannotLocateParentItemException(); } // check for uniqueness if (UniquifyName) { Name = ModelHelper.GetUniqueName(typeof(ComplexType), model, Name); } else { string msg = null; if (ModelHelper.IsUniqueName(typeof(ComplexType), model, Name, false, out msg) == false) { throw new CommandValidationFailedException(msg); } } // create the new item in our model var complexType = new ComplexType(model, null); Debug.Assert(complexType != null, "complexType should not be null"); if (complexType == null) { throw new ItemCreationFailureException(); } // set the name, add it to the parent item complexType.LocalName.Value = Name; model.AddComplexType(complexType); XmlModelHelper.NormalizeAndResolve(complexType); _createdComplexType = complexType; }
/// <summary> /// Creates a ComplexProperty in the passed in entity using ComplexType as a type for it. /// </summary> /// <param name="name">The name of the new property</param> /// <param name="entityType">The entity to create the property in</param> /// <param name="type">The type of the property (can be null)</param> internal CreateComplexPropertyCommand(string name, EntityType entityType, ComplexType type) : this(name, entityType, type, null) { // nothing. }
internal static void ValidateComplexType(ComplexType complexType) { ValidateEFElement(complexType); }
/// <summary> /// Creates a copy of Property from a Clipboard format in the specified ComplexType /// </summary> /// <param name="parentComplexType"></param> /// <param name="clipboardProperty"></param> /// <returns></returns> internal CopyComplexTypePropertyCommand(PropertyClipboardFormat clipboardProperty, ComplexType parentComplexType) { CommandValidation.ValidateComplexType(parentComplexType); _clipboardProperty = clipboardProperty; _parentComplexType = parentComplexType; }
protected override void ProcessPreReqCommands() { var preregCommand1 = GetPreReqCommand(CreateFunctionImportMappingCommand.PrereqId) as CreateFunctionImportMappingCommand; if (preregCommand1 != null) { _functionImportMapping = preregCommand1.FunctionImportMapping; Debug.Assert( _functionImportMapping != null, "CreateFunctionImportMappingCommand command return null value of _functionImportMapping"); } var preregCommand2 = GetPreReqCommand(CreateComplexTypeCommand.PrereqId) as CreateComplexTypeCommand; if (preregCommand2 != null) { _complexType = preregCommand2.ComplexType; Debug.Assert(_complexType != null, "CreateComplexTypeCommand command return null value of ComplexType"); } }
protected override void InvokeInternal(CommandProcessorContext cpc) { var artifact = cpc.EditingContext.GetEFArtifactService().Artifact; if (null == artifact) { Debug.Fail("null artifact not allowed"); return; } // safety check, this should never be hit Debug.Assert(_schemaProcedure != null, "InvokeInternal is called when _schemaProcedure is null"); if (null == _schemaProcedure) { throw new InvalidOperationException("InvokeInternal is called when _schemaProcedure is null."); } var cModel = artifact.ConceptualModel(); if (null == cModel) { Debug.Fail("ConceptualEntityModel not allowed"); return; } var cContainer = cModel.FirstEntityContainer as ConceptualEntityContainer; if (null == cContainer) { Debug.Fail("ConceptualEntityContainer not allowed"); return; } var sModel = artifact.StorageModel(); if (null == sModel) { Debug.Fail("null StorageEntityModel not allowed"); return; } // determine matching Function var funcObj = DatabaseObject.CreateFromSchemaProcedure(_schemaProcedure); var function = ModelHelper.FindFunction(sModel, funcObj); if (null == function) { // in some error scenarios where the model has not been properly created we can be asked to create a FunctionImport for a Function which does not exist // if so just return without creating return; } // do not produce FunctionImports for composable Functions unless _shouldCreateComposableFunctionImport is true if (false == _shouldCreateComposableFunctionImport && function.IsComposable.Value) { return; } // determine FunctionImport name and make sure it is unique var functionImportName = OverrideNameValue; if (String.IsNullOrWhiteSpace(functionImportName)) { if (null == function.LocalName || string.IsNullOrEmpty(function.LocalName.Value)) { Debug.Fail("null or empty LocalName attribute for matching Function " + function); return; } functionImportName = ModelHelper.GetUniqueName(typeof(FunctionImport), cContainer, function.LocalName.Value); } else { #if DEBUG string errorMessage; var isUnique = ModelHelper.IsUniqueName(typeof(FunctionImport), cContainer, functionImportName, false, out errorMessage); Debug.Assert(isUnique, "If we gave CreateMatchingFunctionImportCommand a name, it should have been unique"); #endif } object returnType = null; ComplexType existingComplexTypeReturnType = null; if (OverrideReturnTypeValue == null) { // get return type of the Function returnType = ConstructReturnType(_schemaProcedure, cModel, sModel, functionImportName); if (null == returnType) { Debug.Fail("cannot determine return type for schemaProcedure " + _schemaProcedure); return; } } else { if (OverrideReturnTypeValue.Equals(ModelConstants.NoneValue, StringComparison.Ordinal)) { returnType = Resources.NoneDisplayValueUsedForUX; } else { var rawValue = ModelHelper.UnwrapCollectionAroundFunctionImportReturnType(OverrideReturnTypeValue); // Here we attempt to find the corresponding ReturnType for the given ReturnTypeOverride. // The ReturnTypeOverride will be specified as the actual XAttribute value of the return type if (OverrideEntitySetValue != null) { if (ModelHelper.FindEntitySet(cpc.Artifact.ConceptualModel(), OverrideEntitySetValue) != null) { // ReturnType is an EntityType returnType = ModelHelper.FindEntityTypeViaSymbol(cpc.Artifact.ConceptualModel(), rawValue); } } else if (!ModelHelper.AllPrimitiveTypes(artifact.SchemaVersion).Contains(rawValue)) { // ReturnType is a ComplexType existingComplexTypeReturnType = ModelHelper.FindComplexType(cpc.Artifact.ConceptualModel(), rawValue); returnType = existingComplexTypeReturnType; } else { returnType = rawValue; } } } // Composable functions that do not return collections (e.g. scalar valued functions) are not supported // and should not be imported to the conceptual model if (Resources.NoneDisplayValueUsedForUX.Equals(returnType) && function.IsComposable.Value) { return; } // list of commands to be executed IList <Command> commands = new List <Command>(); // if return type is the name of a ComplexType then create a new matching ComplexType CreateComplexTypeCommand createComplexTypeCommand = null; if (OverrideReturnTypeValue == null && returnType is string && false == Resources.NoneDisplayValueUsedForUX.Equals(returnType)) { createComplexTypeCommand = AddCreateComplexTypeCommands(sModel, returnType as string, _schemaProcedure.RawColumns, commands); } // if we created a ComplexType above then pass that as a pre-req to the CreateFunctionImport command, // otherwise just create the FunctionImport without the pre-req CreateFunctionImportCommand cmdFuncImp; if (createComplexTypeCommand == null) { if (returnType is EdmType) { // For the case where the FunctionImport should have a return type which is not a Complex Type but // simply a C-side primitive type we have to pass the _name_ of the C-side primitive type to // CreateFunctionImportCommand, rather than the type itself returnType = (returnType as EdmType).Name; } cmdFuncImp = new CreateFunctionImportCommand(cContainer, function, functionImportName, returnType); } else { cmdFuncImp = new CreateFunctionImportCommand(cContainer, function, functionImportName, createComplexTypeCommand); } commands.Add(cmdFuncImp); // now create the FunctionImportMapping to map the S-side Function to the C-side FunctionImport if (null != artifact.MappingModel() && null != artifact.MappingModel().FirstEntityContainerMapping) { var cmdFuncImpMapping = new CreateFunctionImportMappingCommand( artifact.MappingModel().FirstEntityContainerMapping, function, cmdFuncImp.Id); cmdFuncImpMapping.AddPreReqCommand(cmdFuncImp); commands.Add(cmdFuncImpMapping); IDictionary <string, string> mapPropertyNameToColumnName = null; if (_schemaProcedure != null) { mapPropertyNameToColumnName = ModelHelper.ConstructComplexTypePropertyNameToColumnNameMapping( _schemaProcedure.RawColumns.Select(c => c.Name).ToList()); } // Create explicit function-import result type mapping if the return type is a complex type. if (createComplexTypeCommand != null) { commands.Add( new CreateFunctionImportTypeMappingCommand(cmdFuncImpMapping, createComplexTypeCommand) { CreateDefaultScalarProperties = true, PropertyNameToColumnNameMap = mapPropertyNameToColumnName }); } else if (OverrideReturnTypeValue != null && existingComplexTypeReturnType != null) { commands.Add( new CreateFunctionImportTypeMappingCommand(cmdFuncImpMapping, existingComplexTypeReturnType) { CreateDefaultScalarProperties = true, PropertyNameToColumnNameMap = mapPropertyNameToColumnName }); } } // now invoke the list of commands if (null != commands) { var cp = new CommandProcessor(cpc, commands); cp.Invoke(); // assign the generated FunctionImport so this command can be used as input for others _generatedFunctionImport = cmdFuncImp.FunctionImport; } }
private ExplorerComplexType AddComplexType(ComplexType complexType) { var explorerComplexType = ModelToExplorerModelXRef.GetNew(_context, complexType, this, typeof(ExplorerComplexType)) as ExplorerComplexType; _complexTypes.Insert(explorerComplexType); return explorerComplexType; }
/// <summary> /// Add commands to create and set the facets for a new complex type property to match the column. /// </summary> internal static void AddCreateComplexTypePropertyCommands( StorageEntityModel storageModel, IRawDataSchemaColumn column, CreateComplexTypeCommand cmdNewComplexType, ComplexType complexType, IList <Command> commands) { // Assert if both cmdNewComplexType and complexType are null or if both are not null. Debug.Assert( ((cmdNewComplexType != null && complexType == null) || (cmdNewComplexType == null && complexType != null)), "Both cmdNewComplexType and complexType are null or both are not null. cmdNewComplexType is null : " + (cmdNewComplexType == null).ToString() + ", complexType is null : " + (complexType == null).ToString()); if ((cmdNewComplexType != null && complexType == null) || (cmdNewComplexType == null && complexType != null)) { // Skip creating the complex type property for a column if the column type is unknown or not supported ( providerDataType == -1 ). if (column.ProviderDataType != -1) { var primitiveType = ModelHelper.GetPrimitiveType(storageModel, column.NativeDataType, column.ProviderDataType); // We only create complex type property if primitive type is known. if (primitiveType != null) { CreateComplexTypePropertyCommand cmdNewComplexTypeProperty = null; // if complex type is not created yet. if (cmdNewComplexType != null) { cmdNewComplexTypeProperty = new CreateComplexTypePropertyCommand( // Automatically "fix" the property Name if it contains bad character. // We need to do this since we don't let the user to change the property name from the Function Import dialog. ModelHelper.CreateValidSimpleIdentifier(column.Name), cmdNewComplexType, primitiveType.GetEdmPrimitiveType().Name, column.IsNullable); commands.Add(cmdNewComplexTypeProperty); } else { cmdNewComplexTypeProperty = new CreateComplexTypePropertyCommand( // Automatically "fix" the property Name if it contains bad character. // We need to do this since we don't let the user to change the property name from the Function Import dialog. ModelHelper.CreateValidSimpleIdentifier(column.Name), complexType, primitiveType.GetEdmPrimitiveType().Name, column.IsNullable); commands.Add(cmdNewComplexTypeProperty); } // We only update the facets that are displayed in Function Import dialog return type view list: // - Nullable. // - Max Size. // - Precision. // - Scale. var cmdSetPropertyFacets = new SetPropertyFacetsCommand( cmdNewComplexTypeProperty , null // Default value , ModelHelper.GetMaxLengthFacetValue(column.Size) , null // Fixed Length , DefaultableValueUIntOrNone.GetFromNullableUInt(column.Precision) , DefaultableValueUIntOrNone.GetFromNullableUInt(column.Scale) , null // unicode , null // collation , null // concurrency mode ); commands.Add(cmdSetPropertyFacets); } } } }
/// <summary> /// Deletes the passed in ComplexType /// </summary> /// <param name="complexType"></param> internal DeleteComplexTypeCommand(ComplexType complexType) : base(complexType) { CommandValidation.ValidateComplexType(complexType); }
/// <summary> /// Creates complex property with a default,unique name and passed complex type /// </summary> /// <param name="cpc"></param> /// <param name="parentComplexType">parent for new property</param> /// <param name="type">type for new property</param> /// <returns></returns> internal static Property CreateDefaultProperty(CommandProcessorContext cpc, ComplexType parentComplexType, ComplexType type) { var name = ModelHelper.GetUniqueName( typeof(ConceptualProperty), parentComplexType, ComplexConceptualProperty.DefaultComplexPropertyName); var cmd = new CreateComplexTypePropertyCommand(name, parentComplexType, type, false); var cp = new CommandProcessor(cpc, cmd); cp.Invoke(); return cmd.Property; }
internal override bool ParseSingleElement(ICollection<XName> unprocessedElements, XElement elem) { // Conceptual EntityModel needs to create Conceptual EntityContainer objects if (elem.Name.LocalName == BaseEntityContainer.ElementName) { if (_entityContainers.Count > 0) { // multiple EntityContainers detected, report an error var msg = String.Format(CultureInfo.CurrentCulture, Resources.TOO_MANY_ENTITY_CONTAINER_ELEMENTS, Namespace.Value); var error = new ErrorInfo( ErrorInfo.Severity.ERROR, msg, this, ErrorCodes.TOO_MANY_ENTITY_CONTAINER_ELEMENTS, ErrorClass.ParseError); Artifact.AddParseErrorForObject(this, error); } var ec = new ConceptualEntityContainer(this, elem); _entityContainers.Add(ec); ec.Parse(unprocessedElements); } else if (elem.Name.LocalName == ComplexType.ElementName) { var complexType = new ComplexType(this, elem); _complexTypes.Add(complexType); complexType.Parse(unprocessedElements); } else if (elem.Name.LocalName == UsingElement.ElementName) { var use = new UsingElement(this, elem); _usings.Add(use); use.Parse(unprocessedElements); } else if (elem.Name.LocalName == EnumType.ElementName) { // Check if enumType that represents the XElement <see DoParse method> var enumType = ModelItemAnnotation.GetModelItem(elem) as EnumType; if (enumType == null || enumType.IsDisposed) { enumType = new EnumType(this, elem); _enumTypes.Add(enumType); enumType.Parse(unprocessedElements); } } else { return base.ParseSingleElement(unprocessedElements, elem); } return true; }
/// <summary> /// Creates a copy of a collection of Properties from clipboard format in the ComplexType /// </summary> internal CopyPropertiesCommand(PropertiesClipboardFormat clipboardProperties, ComplexType complexType) { _clipboardProperties = clipboardProperties; _complexType = complexType; }
internal static void AddChangeComplexTypePropertiesCommands( ComplexType complexType, IDictionary<string, Property> complexTypePropertiesMap, IList<IRawDataSchemaColumn> columns, IList<Command> commands) { Debug.Assert(complexTypePropertiesMap != null, "Parameter complexTypePropertiesMap is null"); if (complexTypePropertiesMap != null) { var columnsDictionary = columns.ToDictionary(c => c.Name); var createdProperties = new HashSet<string>(); var storageModel = complexType.Artifact.StorageModel(); // Iterate current properties decide whether to delete, create, update or skip. foreach (var propertyName in complexTypePropertiesMap.Keys) { // If the column is not found in columns dictionary delete it. if (!columnsDictionary.ContainsKey(propertyName)) { commands.Add(complexTypePropertiesMap[propertyName].GetDeleteCommand()); } // Match is found between schema column and complex type property. else { var complexTypeProperty = complexTypePropertiesMap[propertyName]; var schemaColumn = columnsDictionary[propertyName]; // Special case if the property is a complex property, we just need to delete it. if (complexTypeProperty is ComplexConceptualProperty) { // Delete the complex property commands.Add(complexTypeProperty.GetDeleteCommand()); // Create a new complex property AddCreateComplexTypePropertyCommands(storageModel, schemaColumn, null, complexType, commands); // Add the property to the "created-list" so we don't create the property in the second pass. createdProperties.Add(propertyName); } // If ProviderDataType == -1 (Unsupported type) we should skip the sync operation else if (schemaColumn.ProviderDataType != -1) { // Update the ComplexType's property to look like the schemaColumn var primitiveType = ModelHelper.GetPrimitiveType( storageModel, schemaColumn.NativeDataType, schemaColumn.ProviderDataType); // PrimitiveType is null if there is no compatible EF type for the schema column type. if (primitiveType != null) { // sync the property type commands.Add(new ChangePropertyTypeCommand(complexTypeProperty, primitiveType.GetEdmPrimitiveType().Name)); // sync the property facets. // We only update the facets that are displayed in Function Import dialog return type view list: // - Nullable. // - Max Size. // - Precision. // - Scale. commands.Add(new ChangePropertyTypeNullableCommand(complexTypeProperty, schemaColumn.IsNullable)); commands.Add( new SetPropertyFacetsCommand( complexTypeProperty , null // Default value , ModelHelper.GetMaxLengthFacetValue(schemaColumn.Size) // Size or MaxLength , null // Fixed Length , DefaultableValueUIntOrNone.GetFromNullableUInt(schemaColumn.Precision) , DefaultableValueUIntOrNone.GetFromNullableUInt(schemaColumn.Scale) , null // unicode , null // collation , null // concurrency mode )); } } } } // Second pass: Iterate columns list to add columns that are not in complex type properties foreach (var columnName in columnsDictionary.Keys) { if (false == complexTypePropertiesMap.ContainsKey(columnName) && false == createdProperties.Contains(columnName)) { AddCreateComplexTypePropertyCommands(storageModel, columnsDictionary[columnName], null, complexType, commands); } } } }
public ExplorerComplexType(EditingContext context, ComplexType complexType, ExplorerEFElement parent) : base(context, complexType, parent) { // do nothing }
/// <summary> /// Creates a copy of Property from a Clipboard format in the specified ComplexType /// </summary> /// <param name="complexType"></param> /// <param name="clipboardProperty"></param> /// <returns></returns> internal CopyPropertyCommand(PropertyClipboardFormat clipboardProperty, ComplexType complexType) { CommandValidation.ValidateComplexType(complexType); _clipboardProperty = clipboardProperty; _complexType = complexType; }
internal static void AddChangeComplexTypePropertiesCommands( ComplexType complexType, IDictionary <string, Property> complexTypePropertiesMap, IList <IRawDataSchemaColumn> columns, IList <Command> commands) { Debug.Assert(complexTypePropertiesMap != null, "Parameter complexTypePropertiesMap is null"); if (complexTypePropertiesMap != null) { var columnsDictionary = columns.ToDictionary(c => c.Name); var createdProperties = new HashSet <string>(); var storageModel = complexType.Artifact.StorageModel(); // Iterate current properties decide whether to delete, create, update or skip. foreach (var propertyName in complexTypePropertiesMap.Keys) { // If the column is not found in columns dictionary delete it. if (!columnsDictionary.ContainsKey(propertyName)) { commands.Add(complexTypePropertiesMap[propertyName].GetDeleteCommand()); } // Match is found between schema column and complex type property. else { var complexTypeProperty = complexTypePropertiesMap[propertyName]; var schemaColumn = columnsDictionary[propertyName]; // Special case if the property is a complex property, we just need to delete it. if (complexTypeProperty is ComplexConceptualProperty) { // Delete the complex property commands.Add(complexTypeProperty.GetDeleteCommand()); // Create a new complex property AddCreateComplexTypePropertyCommands(storageModel, schemaColumn, null, complexType, commands); // Add the property to the "created-list" so we don't create the property in the second pass. createdProperties.Add(propertyName); } // If ProviderDataType == -1 (Unsupported type) we should skip the sync operation else if (schemaColumn.ProviderDataType != -1) { // Update the ComplexType's property to look like the schemaColumn var primitiveType = ModelHelper.GetPrimitiveType( storageModel, schemaColumn.NativeDataType, schemaColumn.ProviderDataType); // PrimitiveType is null if there is no compatible EF type for the schema column type. if (primitiveType != null) { // sync the property type commands.Add(new ChangePropertyTypeCommand(complexTypeProperty, primitiveType.GetEdmPrimitiveType().Name)); // sync the property facets. // We only update the facets that are displayed in Function Import dialog return type view list: // - Nullable. // - Max Size. // - Precision. // - Scale. commands.Add(new ChangePropertyTypeNullableCommand(complexTypeProperty, schemaColumn.IsNullable)); commands.Add( new SetPropertyFacetsCommand( complexTypeProperty , null // Default value , ModelHelper.GetMaxLengthFacetValue(schemaColumn.Size) // Size or MaxLength , null // Fixed Length , DefaultableValueUIntOrNone.GetFromNullableUInt(schemaColumn.Precision) , DefaultableValueUIntOrNone.GetFromNullableUInt(schemaColumn.Scale) , null // unicode , null // collation , null // concurrency mode )); } } } } // Second pass: Iterate columns list to add columns that are not in complex type properties foreach (var columnName in columnsDictionary.Keys) { if (false == complexTypePropertiesMap.ContainsKey(columnName) && false == createdProperties.Contains(columnName)) { AddCreateComplexTypePropertyCommands(storageModel, columnsDictionary[columnName], null, complexType, commands); } } } }
/// <summary> /// Add commands to create and set the facets for a new complex type property to match the column. /// </summary> internal static void AddCreateComplexTypePropertyCommands( StorageEntityModel storageModel, IRawDataSchemaColumn column, CreateComplexTypeCommand cmdNewComplexType, ComplexType complexType, IList<Command> commands) { // Assert if both cmdNewComplexType and complexType are null or if both are not null. Debug.Assert( ((cmdNewComplexType != null && complexType == null) || (cmdNewComplexType == null && complexType != null)), "Both cmdNewComplexType and complexType are null or both are not null. cmdNewComplexType is null : " + (cmdNewComplexType == null).ToString() + ", complexType is null : " + (complexType == null).ToString()); if ((cmdNewComplexType != null && complexType == null) || (cmdNewComplexType == null && complexType != null)) { // Skip creating the complex type property for a column if the column type is unknown or not supported ( providerDataType == -1 ). if (column.ProviderDataType != -1) { var primitiveType = ModelHelper.GetPrimitiveType(storageModel, column.NativeDataType, column.ProviderDataType); // We only create complex type property if primitive type is known. if (primitiveType != null) { CreateComplexTypePropertyCommand cmdNewComplexTypeProperty = null; // if complex type is not created yet. if (cmdNewComplexType != null) { cmdNewComplexTypeProperty = new CreateComplexTypePropertyCommand( // Automatically "fix" the property Name if it contains bad character. // We need to do this since we don't let the user to change the property name from the Function Import dialog. ModelHelper.CreateValidSimpleIdentifier(column.Name), cmdNewComplexType, primitiveType.GetEdmPrimitiveType().Name, column.IsNullable); commands.Add(cmdNewComplexTypeProperty); } else { cmdNewComplexTypeProperty = new CreateComplexTypePropertyCommand( // Automatically "fix" the property Name if it contains bad character. // We need to do this since we don't let the user to change the property name from the Function Import dialog. ModelHelper.CreateValidSimpleIdentifier(column.Name), complexType, primitiveType.GetEdmPrimitiveType().Name, column.IsNullable); commands.Add(cmdNewComplexTypeProperty); } // We only update the facets that are displayed in Function Import dialog return type view list: // - Nullable. // - Max Size. // - Precision. // - Scale. var cmdSetPropertyFacets = new SetPropertyFacetsCommand( cmdNewComplexTypeProperty , null // Default value , ModelHelper.GetMaxLengthFacetValue(column.Size) , null // Fixed Length , DefaultableValueUIntOrNone.GetFromNullableUInt(column.Precision) , DefaultableValueUIntOrNone.GetFromNullableUInt(column.Scale) , null // unicode , null // collation , null // concurrency mode ); commands.Add(cmdSetPropertyFacets); } } } }
internal void AddComplexType(ComplexType complexType) { _complexTypes.Add(complexType); }