예제 #1
0
 internal static void ValidateConceptualEntityContainer(ConceptualEntityContainer conceptualEntityContainer)
 {
     ValidateEFElement(conceptualEntityContainer);
     var conceptualModel = conceptualEntityContainer.Parent as BaseEntityModel;
     Debug.Assert(conceptualModel != null, "The ConceptualEntityContainer sent must be in a BaseEntityModel");
     Debug.Assert(conceptualModel.IsCSDL, "The ConceptualEntityContainer sent must be passed in from the conceptual model");
 }
        /// <summary>
        ///     Creates a FunctionImport element that mimics the nodes under the Function element.
        /// </summary>
        /// <param name="function"></param>
        internal CreateFunctionImportCommand(ConceptualEntityContainer ec, Function function, string functionImportName, object returnType)
        {
            CommandValidation.ValidateConceptualEntityContainer(ec);
            CommandValidation.ValidateFunction(function);

            Container = ec;
            Function = function;
            FunctionImportName = functionImportName;
            ReturnSingleType = returnType;
        }
        /// <summary>
        ///     Create a Function Import whose return type being created in passed in CreateComplexTypeCommand.
        /// </summary>
        /// <param name="ec"></param>
        /// <param name="function"></param>
        /// <param name="functionImportName"></param>
        /// <param name="prereqCommand"></param>
        internal CreateFunctionImportCommand(
            ConceptualEntityContainer ec, Function function, string functionImportName, CreateComplexTypeCommand prereqCommand)
        {
            ValidatePrereqCommand(prereqCommand);
            CommandValidation.ValidateConceptualEntityContainer(ec);
            CommandValidation.ValidateFunction(function);

            Container = ec;
            Function = function;
            FunctionImportName = functionImportName;
            AddPreReqCommand(prereqCommand);
        }
        /// <summary>
        ///     Change various aspects of the passed in Function Import. The passed in function import will be modified based on the
        ///     other passed-in parameters (null is not ignored).
        /// </summary>
        /// <param name="fi"></param>
        /// <param name="function"></param>
        /// <param name="functionImportName"></param>
        /// <param name="returnType">Object of type EntityType or string representing the primitive type/'None'</param>
        internal ChangeFunctionImportCommand(
            ConceptualEntityContainer ec, FunctionImport fi, Function function, string functionImportName,
            BoolOrNone functionImportIsComposable, bool changeReturnType, object returnType)
        {
            CommandValidation.ValidateFunctionImport(fi);
            ValidateString(functionImportName);

            FunctionImport = fi;
            Function = function;
            EntityContainer = ec;
            FunctionImportName = functionImportName;
            FunctionImportIsComposable = functionImportIsComposable;
            ChangeReturnType = changeReturnType;
            ReturnSingleType = returnType;
            _efContainerToBeNormalized = new List<EFContainer>();
        }
 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>
        ///     Change various aspects of the passed in Function Import. The passed in function import will be modified based on the
        ///     other passed-in parameters (null is not ignored).
        /// </summary>
        /// <param name="ec"></param>
        /// <param name="fi"></param>
        /// <param name="function"></param>
        /// <param name="functionImportName"></param>
        /// <param name="prereqCommand"></param>
        internal ChangeFunctionImportCommand(
            ConceptualEntityContainer ec, FunctionImport fi, Function function, string functionImportName,
            BoolOrNone functionImportIsComposable, CreateComplexTypeCommand prereqCommand)
        {
            ValidatePrereqCommand(prereqCommand);
            CommandValidation.ValidateFunctionImport(fi);
            ValidateString(functionImportName);

            FunctionImport = fi;
            Function = function;
            EntityContainer = ec;
            FunctionImportName = functionImportName;
            FunctionImportIsComposable = functionImportIsComposable;
            ChangeReturnType = true;
            _efContainerToBeNormalized = new List<EFContainer>();
            AddPreReqCommand(prereqCommand);
        }
 public ExplorerConceptualEntityContainer(
     EditingContext context,
     ConceptualEntityContainer entityContainer, ExplorerEFElement parent)
     : base(context, entityContainer, parent)
 {
 }
 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;
 }
        private static EntityDesignNewFunctionImportResult ShowNewFunctionImportDialog(
            Function selectedSproc,
            string selectedSprocName,
            StorageEntityModel sModel,
            ConceptualEntityModel cModel,
            ConceptualEntityContainer cContainer,
            string dialogTitle,
            Object selectedObject)
        {
            using (var dialog = new NewFunctionImportDialog(
                selectedSproc,
                selectedSprocName,
                sModel.Functions(),
                cModel.ComplexTypes(),
                cModel.EntityTypes(),
                cContainer,
                selectedObject))
            {
                dialog.Text = dialogTitle;

                var dialogResult = dialog.ShowDialog();

                var result = new EntityDesignNewFunctionImportResult
                    {
                        DialogResult = dialogResult,
                        Function = dialog.Function,
                        FunctionName = dialog.FunctionImportName,
                        IsComposable = dialog.IsComposable,
                        ReturnType = dialog.ReturnType,
                        Schema = dialog.Schema
                    };

                return result;
            }
        }
        internal static FunctionImport CreateFunctionImport(
            EditingContext editingContext,
            EFArtifact artifact,
            Function selectedSproc,
            StorageEntityModel sModel,
            ConceptualEntityModel cModel,
            ConceptualEntityContainer cContainer,
            EntityType entityType,
            string originatingId)
        {
            FunctionImport functionImportResult = null;

            Debug.Assert(editingContext != null, "editingContext should not be null");
            Debug.Assert(artifact != null, "artifact should not be null");
            Debug.Assert(!string.IsNullOrEmpty(originatingId), "originatingId should not be null or empty");

            // show dialog appropriate to framework version
            var result = ShowNewFunctionImportDialog(
                selectedSproc,
                null /* selectedSprocName Parameter */,
                sModel,
                cModel,
                cContainer,
                DialogsResource.NewFunctionImportDialog_AddFunctionImportTitle,
                entityType);

            // if user selected OK on the dialog then create the FunctionImport
            if (DialogResult.OK == result.DialogResult)
            {
                var commands = new Collection<Command>();

                CreateComplexTypeCommand createComplexTypeCommand = null;

                // Make the decision based on what is returned by the dialog.
                // If return type is a string and result schema is not null, that means the user would like create a new complex type for the function import return.
                if (result.ReturnType is string
                    && result.Schema != null)
                {
                    createComplexTypeCommand = CreateMatchingFunctionImportCommand.AddCreateComplexTypeCommands(
                        sModel, result.ReturnType as string, result.Schema.RawColumns, commands);
                }
                    // If ReturnType is a complex type and result schema is not null, the complex type needs to be updated to be in sync with schema columns.
                else if (result.ReturnType is ComplexType
                         && result.Schema != null)
                {
                    var complexType = result.ReturnType as ComplexType;
                    var propertiesDictionary = complexType.Properties().ToDictionary(p => p.LocalName.Value);
                    CreateMatchingFunctionImportCommand.AddChangeComplexTypePropertiesCommands(
                        complexType, propertiesDictionary, result.Schema.RawColumns, commands);
                }

                CreateFunctionImportCommand cmdFuncImp;
                if (createComplexTypeCommand == null)
                {
                    cmdFuncImp = new CreateFunctionImportCommand(cContainer, result.Function, result.FunctionName, result.ReturnType);
                }
                else
                {
                    // Pass in the pre-req command to create complex type to the command.
                    cmdFuncImp = new CreateFunctionImportCommand(cContainer, result.Function, result.FunctionName, createComplexTypeCommand);
                }

                commands.Add(cmdFuncImp);

                // now add a FunctionImport and a FunctionImportMapping (if appropriate)
                if (artifact.MappingModel() != null
                    && artifact.MappingModel().FirstEntityContainerMapping != null)
                {
                    var cmdFuncImpMapping = new CreateFunctionImportMappingCommand(
                        artifact.MappingModel().FirstEntityContainerMapping, result.Function, cmdFuncImp.Id);
                    cmdFuncImpMapping.AddPreReqCommand(cmdFuncImp);
                    commands.Add(cmdFuncImpMapping);

                    IDictionary<string, string> mapPropertyNameToColumnName = null;
                    if (result.Schema != null)
                    {
                        mapPropertyNameToColumnName =
                            ModelHelper.ConstructComplexTypePropertyNameToColumnNameMapping(
                                result.Schema.Columns.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 (result.ReturnType is ComplexType)
                    {
                        commands.Add(
                            new CreateFunctionImportTypeMappingCommand(cmdFuncImpMapping, result.ReturnType as ComplexType)
                                {
                                    CreateDefaultScalarProperties = true,
                                    PropertyNameToColumnNameMap = mapPropertyNameToColumnName
                                });
                    }
                }

                var cp = new CommandProcessor(editingContext, originatingId, Resources.Tx_CreateFunctionImport, commands);
                cp.Invoke();

                functionImportResult = cmdFuncImp.FunctionImport;
                NavigateToFunction(functionImportResult);
            }

            return functionImportResult;
        }
        internal static void EditFunctionImport(
            EditingContext editingContext,
            FunctionImport functionImport,
            StorageEntityModel sModel,
            ConceptualEntityModel cModel,
            ConceptualEntityContainer cContainer,
            object selectedObject,
            string originatingId)
        {
            Debug.Assert(editingContext != null, "editingContext should not be null");
            Debug.Assert(!string.IsNullOrEmpty(originatingId), "originatingId should not be null or empty");

            // show dialog appropriate to framework version
            var result = ShowNewFunctionImportDialog(
                functionImport.Function,
                functionImport.LocalName.Value,
                sModel,
                cModel,
                cContainer,
                DialogsResource.NewFunctionImportDialog_EditFunctionImportTitle,
                selectedObject);

            // if user selected OK on the dialog then create the FunctionImport
            if (DialogResult.OK == result.DialogResult)
            {
                var commands = new List<Command>();
                var cp = new CommandProcessor(editingContext, originatingId, Resources.Tx_UpdateFunctionImport);
                CreateComplexTypeCommand createComplexTypeCommand = null;

                // Make the decision based on what is returned by the dialog.
                // If return type is a string and result schema is not null, that means the user would like to create a new complex type for the function import return.
                if (result.ReturnType is string
                    && result.Schema != null)
                {
                    createComplexTypeCommand = CreateMatchingFunctionImportCommand.AddCreateComplexTypeCommands(
                        sModel, result.ReturnType as string, result.Schema.RawColumns, commands);
                }
                    // If ReturnType is a complex type and result schema is not null, the complex type needs to be updated to be in sync with schema columns.
                else if (result.ReturnType is ComplexType
                         && result.Schema != null)
                {
                    var complexType = result.ReturnType as ComplexType;
                    // Create Column properties dictionary. The keys will be either property's type-mapping column name if availabe or property's name.
                    var propertiesDictionary =
                        complexType.Properties().ToDictionary(p => EdmUtils.GetFunctionImportResultColumnName(functionImport, p));
                    CreateMatchingFunctionImportCommand.AddChangeComplexTypePropertiesCommands(
                        complexType, propertiesDictionary, result.Schema.RawColumns, commands);
                }

                // construct Dictionary mapping property name to column name for FunctionImportMapping
                IDictionary<string, string> mapPropertyNameToColumnName = null;
                if (result.Schema != null)
                {
                    mapPropertyNameToColumnName =
                        ModelHelper.ConstructComplexTypePropertyNameToColumnNameMapping(result.Schema.Columns.Select(c => c.Name).ToList());
                }

                // change the FunctionImport and FunctionImportMapping to match
                ChangeFunctionImportCommand cmdFuncImpSproc = null;
                // if result.IsComposable is true then set to True, but if false then use None if existing value is None, otherwise False
                var resultIsComposable = (result.IsComposable
                                              ? BoolOrNone.TrueValue
                                              : (BoolOrNone.NoneValue == functionImport.IsComposable.Value
                                                     ? BoolOrNone.NoneValue
                                                     : BoolOrNone.FalseValue));
                if (createComplexTypeCommand == null)
                {
                    cmdFuncImpSproc = new ChangeFunctionImportCommand(
                        cContainer, functionImport, result.Function, result.FunctionName, resultIsComposable, true, result.ReturnType);
                    // Create explicit function-import result type mapping if the return type is a complex type.
                    if (result.ReturnType is ComplexType)
                    {
                        cmdFuncImpSproc.PostInvokeEvent += (o, eventArgs) =>
                            {
                                if (functionImport != null
                                    && functionImport.FunctionImportMapping != null)
                                {
                                    // CreateFunctionImportTypeMappingCommand will be no op function-import's return is unchanged.
                                    CommandProcessor.InvokeSingleCommand(
                                        cp.CommandProcessorContext
                                        ,
                                        new CreateFunctionImportTypeMappingCommand(
                                            functionImport.FunctionImportMapping, result.ReturnType as ComplexType)
                                            {
                                                CreateDefaultScalarProperties = true,
                                                PropertyNameToColumnNameMap = mapPropertyNameToColumnName
                                            });
                                }
                            };
                    }
                }
                else
                {
                    // Pass in the pre-req command to create complex type to the command.
                    cmdFuncImpSproc = new ChangeFunctionImportCommand(
                        cContainer, functionImport, result.Function, result.FunctionName,
                        resultIsComposable, createComplexTypeCommand);
                    // Create explicit function-import result type mapping if the return type is a complex type.
                    cmdFuncImpSproc.PostInvokeEvent += (o, eventArgs) =>
                        {
                            if (functionImport != null
                                && functionImport.FunctionImportMapping != null)
                            {
                                CommandProcessor.InvokeSingleCommand(
                                    cp.CommandProcessorContext,
                                    new CreateFunctionImportTypeMappingCommand(
                                        functionImport.FunctionImportMapping, createComplexTypeCommand)
                                        {
                                            CreateDefaultScalarProperties = true,
                                            PropertyNameToColumnNameMap = mapPropertyNameToColumnName
                                        });
                            }
                        };
                }
                commands.Add(cmdFuncImpSproc);
                commands.ForEach(x => cp.EnqueueCommand(x));
                cp.Invoke();
            }
        }
        internal NewFunctionImportDialog(
            Function baseFunction,
            string functionImportName,
            ICollection<Function> functions,
            IEnumerable<ComplexType> complexTypes,
            IEnumerable<EntityType> entityTypes,
            ConceptualEntityContainer container,
            object selectedElement)
        {
            // The dialog 3 mode:
            // - New function import: to create a new function import
            // - Full edit function import: the dialog is launched from model browser; all fields are editable
            _mode = DialogMode.New;
            _editedFunctionImport = container.FunctionImports().Where(x => x.LocalName.Value == functionImportName).FirstOrDefault();
            if (_editedFunctionImport != null)
            {
                _mode = DialogMode.FullEdit;
            }
            _functions = functions;
            _lastGeneratedStoredProc = null;
            _container = container;
            _updateSelectedComplexType = false;
            InitializeSupportedFeatures();
            InitializeComponent();
            InitializeDialogFont();

            // set tooltip on functionImportComposableCheckBox if not supported
            if (false == _composableFunctionImportFeatureState.IsEnabled())
            {
                var isComposableToolTipMsg = string.Format(
                    CultureInfo.CurrentCulture, DialogsResource.NewFunctionImportDialog_IsComposableTooltipText,
                    EntityFrameworkVersion.Version2);
                var isComposableToolTip = new ToolTip();
                isComposableToolTip.ShowAlways = true; // show even if control inactive
                isComposableToolTip.SetToolTip(functionImportComposableCheckBox, isComposableToolTipMsg);
            }

            // once the components are initialized, check the functionImportComposableCheckBox if appropriate
            if (_composableFunctionImportFeatureState.IsEnabled())
            {
                if (DialogMode.FullEdit == _mode)
                {
                    functionImportComposableCheckBox.Checked = (BoolOrNone.TrueValue == _editedFunctionImport.IsComposable.Value);
                }
                else
                {
                    Debug.Assert(_mode == DialogMode.New, "Unexpected mode");

                    functionImportComposableCheckBox.Checked = baseFunction != null && baseFunction.IsComposable.Value;
                }
            }

            // Hide the Update button/GetColumnInformation frame if this functionality isn't allowed
            if (!_getColumnInformationFeatureState.IsVisible())
            {
                updateComplexTypeButton.Visible = false;
                returnTypeShapeGroup.Visible = false;
                if (ClientSize.Height > returnTypeShapeGroup.Height)
                {
                    var newSize = new Size(Size.Width, Size.Height - returnTypeShapeGroup.Height);
                    MinimumSize = newSize;
                    Size = newSize;
                }
            }

            PopulateComboBoxes(complexTypes, entityTypes, functions);
            UpdateStateComboBoxes(selectedElement, baseFunction, functionImportName);
            SetComplexTypeTooltip();
            CheckOkButtonEnabled();
            UpdateReturnTypeComboBoxesState();
            UpdateReturnTypeInfoAreaState();
            SetCreateNewComplexTypeButtonProperties();

            if (components == null)
            {
                components = new Container();
            }
            // Since Visual Studio has already defined Dispose method in the generated file(designer.cs),
            // we instantiates Diposer class that calls our custom dispose method when Form is disposed.
            components.Add(new Disposer(OnDispose));
        }