internal CreateFunctionImportMappingCommand(EntityContainerMapping em, Function function, FunctionImport functionImport)
     : base(PrereqId)
 {
     ContainerMapping = em;
     Function = function;
     FunctionImport = functionImport;
 }
        private void CompareEntityContainer(EntityContainer expectedEntityContainer, EntityContainer actualEntityContainer)
        {
            foreach (EntitySet expectedEntitySet in expectedEntityContainer.EntitySets)
            {
                List <EntitySet> entitySets = actualEntityContainer.EntitySets.Where(es => es.Name == expectedEntitySet.Name).ToList();
                if (!this.WriteErrorIfFalse(entitySets.Count == 1, "Cannot find entitySet '{0}'", expectedEntitySet.Name))
                {
                    EntitySet yentitySet = entitySets.Single();
                    this.CompareEntitySet(expectedEntitySet, yentitySet);
                }
            }

            foreach (AssociationSet expectedAssociationSet in expectedEntityContainer.AssociationSets)
            {
                List <AssociationSet> associationSets = actualEntityContainer.AssociationSets.Where(asSet => asSet.Name == expectedAssociationSet.Name).ToList();
                if (!this.WriteErrorIfFalse(associationSets.Count == 1, "Cannot find associationSet '{0}'", expectedAssociationSet.Name))
                {
                    AssociationSet actualassociationSet = associationSets.Single();
                    this.CompareAssociationSet(expectedAssociationSet, actualassociationSet);
                }
            }

            foreach (FunctionImport expectedFunctionImport in expectedEntityContainer.FunctionImports)
            {
                List <FunctionImport> functionImports = actualEntityContainer.FunctionImports.Where(fi => fi.Name == expectedFunctionImport.Name && fi.Parameters.Count() == expectedFunctionImport.Parameters.Count()).ToList();
                if (!this.WriteErrorIfFalse(functionImports.Count == 1, "Cannot find FunctionImport '{0}'", expectedFunctionImport.Name))
                {
                    FunctionImport actualFunctionImport = functionImports.Single();
                    this.CompareFunctionImport(expectedFunctionImport, actualFunctionImport);
                }
            }
        }
Esempio n. 3
0
        private void CloneContainerContents(EntityContainer baseContainer, EntityContainer extendedContainer)
        {
            foreach (var entitySet in baseContainer.EntitySets)
            {
                var clonedEntitySet = new EntitySet(entitySet.Name, entitySet.EntityType);
                extendedContainer.Add(clonedEntitySet);
            }

            foreach (var associationSet in baseContainer.AssociationSets)
            {
                var clonedAssociationSet = new AssociationSet(associationSet.Name, associationSet.AssociationType);
                foreach (var setEnd in associationSet.Ends)
                {
                    clonedAssociationSet.Add(new AssociationSetEnd(setEnd.AssociationEnd, setEnd.EntitySet.Name));
                }

                extendedContainer.Add(clonedAssociationSet);
            }

            foreach (var functionImport in baseContainer.FunctionImports)
            {
                var clonedFunctionImport = new FunctionImport(functionImport.Name);
                foreach (var returnType in functionImport.ReturnTypes)
                {
                    clonedFunctionImport.ReturnTypes.Add(returnType);
                }

                foreach (var parameter in functionImport.Parameters)
                {
                    clonedFunctionImport.Add(new FunctionParameter(parameter.Name, parameter.DataType, parameter.Mode));
                }

                extendedContainer.Add(clonedFunctionImport);
            }
        }
Esempio n. 4
0
        private void CompareFunctionImport(FunctionImport expectedFunctionImport, FunctionImport actualFunctionImport)
        {
            this.SatisfiesCondition(expectedFunctionImport.ReturnTypes.Count == actualFunctionImport.ReturnTypes.Count, "FunctionImport '{0}' has the wrong number of return types. Expected:{1} Actual:{2}.", expectedFunctionImport.Name, expectedFunctionImport.ReturnTypes.Count, actualFunctionImport.ReturnTypes.Count);
            for (int i = 0; i < expectedFunctionImport.ReturnTypes.Count; i++)
            {
                var expectedReturnType = expectedFunctionImport.ReturnTypes[i];
                var actualReturnType   = actualFunctionImport.ReturnTypes[i];
                if (expectedReturnType.EntitySet == null)
                {
                    this.SatisfiesCondition(actualReturnType.EntitySet == null, "FunctionImport '{0}' should not have EntitySet.", expectedFunctionImport.Name);
                }
                else
                {
                    this.SatisfiesEquals(
                        expectedReturnType.EntitySet.Name,
                        actualReturnType.EntitySet.Name,
                        "EntitySet on FunctionImport '{0}' does not match.",
                        expectedFunctionImport.Name);
                }

                this.CompareReturnType(
                    expectedReturnType.DataType,
                    actualReturnType.DataType,
                    string.Format(CultureInfo.InvariantCulture, "FunctionImport '{0}'", expectedFunctionImport.Name));
            }

            this.CompareParameters(
                expectedFunctionImport.Parameters,
                actualFunctionImport.Parameters,
                string.Format(CultureInfo.InvariantCulture, "FunctionImport '{0}'", expectedFunctionImport.Name));
        }
Esempio n. 5
0
 internal CreateFunctionImportMappingCommand(EntityContainerMapping em, Function function, FunctionImport functionImport)
     : base(PrereqId)
 {
     ContainerMapping = em;
     Function         = function;
     FunctionImport   = functionImport;
 }
        private EntityContainer ConvertToTaupoEntityContainer(IEdmEntityContainer edmEntityContainer)
        {
            var taupoEntityContainer = new EntityContainer(edmEntityContainer.Name);

            foreach (var edmEntitySet in edmEntityContainer.Elements.OfType <IEdmEntitySet>())
            {
                EntitySet taupoEntitySet = this.ConvertToTaupoEntitySet(edmEntitySet);
                taupoEntityContainer.Add(taupoEntitySet);

                foreach (var edmNavigationProperty in edmEntitySet.NavigationPropertyBindings.Select(t => t.NavigationProperty))
                {
                    if (!this.associationRegistry.IsAssociationSetRegistered(edmEntitySet, edmNavigationProperty))
                    {
                        this.associationRegistry.RegisterAssociationSet(edmEntitySet, edmNavigationProperty);
                    }
                }
            }

            foreach (var edmFunctionImport in edmEntityContainer.Elements.OfType <IEdmOperationImport>())
            {
                FunctionImport taupoFunctionImport = this.ConvertToTaupoFunctionImport(edmFunctionImport);
                taupoEntityContainer.Add(taupoFunctionImport);
            }

            this.ConvertAnnotationsIntoTaupo(edmEntityContainer, taupoEntityContainer);
            return(taupoEntityContainer);
        }
            /// <summary>
            /// Returns the function import for a parameters payload.
            /// </summary>
            /// <param name="expectedTypeAnnotation">The expected type annotation.</param>
            /// <param name="model">The model to get the function import from.</param>
            /// <returns>Returns the function import for a parameters payload.</returns>
            private static IEdmOperationImport GetExpectedFunctionImport(ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, IEdmModel model)
            {
                ExceptionUtilities.Assert(model != null, "model != null");

                if (expectedTypeAnnotation != null)
                {
                    if (expectedTypeAnnotation.ProductFunctionImport != null)
                    {
                        return(expectedTypeAnnotation.ProductFunctionImport);
                    }
                    FunctionImport functionImport = expectedTypeAnnotation.FunctionImport;
                    if (functionImport != null)
                    {
                        var container       = model.FindEntityContainer(functionImport.Container.FullName);
                        var functionImports = container.FindOperationImports(functionImport.Name);
                        if (functionImports != null && functionImports.Any())
                        {
                            // Note that we don't support overload for Actions. Single() will throw if the model is invalid.
                            return(functionImports.Single());
                        }
                    }
                }

                return(null);
            }
Esempio n. 8
0
        /// <summary>
        /// Compares the actual function import against the expected.
        /// </summary>
        /// <param name="expectedFunctionImport">expected function import</param>
        /// <param name="actualFunctionImport">actual import</param>
        /// <remarks>This implementation also compares the annotations on the function import.</remarks>
        protected override void CompareFunctionImport(FunctionImport expectedFunctionImport, FunctionImport actualFunctionImport)
        {
            // TODO: Add support for checking annotations to the EntityModelSchemaComparer.CompareFunctionImport method.
            // We have overridden the base method because we wanted to minimize the impact of this change to other existing Taupo test cases.
            base.CompareFunctionImport(expectedFunctionImport, actualFunctionImport);

            if (!this.WriteErrorIfFalse(
                    expectedFunctionImport.Annotations.OfType <AttributeAnnotation>().Count() == actualFunctionImport.Annotations.OfType <AttributeAnnotation>().Count(),
                    "Expected and actual count of the FunctionImport annotations did not match."))
            {
                // verify annotations
                foreach (AttributeAnnotation expectedAnnotation in expectedFunctionImport.Annotations.OfType <AttributeAnnotation>())
                {
                    AttributeAnnotation actualAnnotation = actualFunctionImport.Annotations.OfType <AttributeAnnotation>().SingleOrDefault(
                        ann => ann.Content.Name.Equals(expectedAnnotation.Content.Name));

                    if (!this.WriteErrorIfFalse(actualAnnotation != null, "The expected annotation named '{0}' was not found in the FunctionImport.", expectedAnnotation.Content.Name.LocalName))
                    {
                        this.WriteErrorIfFalse(
                            actualAnnotation.Content.Value == expectedAnnotation.Content.Value,
                            "FunctionImport annotation not equal. Expected {0}, Actual: {1}",
                            expectedAnnotation.Content.Value,
                            actualAnnotation.Content.Value);
                    }
                }
            }
        }
Esempio n. 9
0
        private ExplorerFunctionImport AddFunctionImport(FunctionImport funcImport)
        {
            var explorerFuncImport =
                ModelToExplorerModelXRef.GetNew(_context, funcImport, this, typeof(ExplorerFunctionImport)) as ExplorerFunctionImport;

            _functionImports.Insert(explorerFuncImport);
            return(explorerFuncImport);
        }
        internal SetFunctionImportSprocCommand(FunctionImport functionImport, Function function)
        {
            CommandValidation.ValidateFunctionImport(functionImport);
            CommandValidation.ValidateFunction(function);

            _functionImport = functionImport;
            _function = function;
        }
Esempio n. 11
0
        internal SetFunctionImportSprocCommand(FunctionImport functionImport, Function function)
        {
            CommandValidation.ValidateFunctionImport(functionImport);
            CommandValidation.ValidateFunction(function);

            _functionImport = functionImport;
            _function       = function;
        }
Esempio n. 12
0
        /// <summary>
        /// Visit function import
        /// </summary>
        /// <param name="functionImport">function import to visit</param>
        protected virtual void VisitFunctionImport(FunctionImport functionImport)
        {
            this.VisitAnnotatedItem(functionImport);

            foreach (var parameter in functionImport.Parameters)
            {
                this.VisitFunctionParameter(parameter);
            }
        }
Esempio n. 13
0
        private bool FunctionImportSignaturesAreSame(FunctionImport f1, FunctionImport f2)
        {
            if (f1.Name != f2.Name)
            {
                return(false);
            }

            return(this.ParametersMatch(f1.Parameters, f2.Parameters));
        }
Esempio n. 14
0
        /// <summary>
        /// Creates a new parameter for the specified function import.
        /// </summary>
        /// <param name="functionImport">The <see cref="FunctionImport"/> to add the parameter to.</param>
        /// <param name="name">The local name of the parameter.</param>
        /// <param name="dataType">The type of the function parameter.</param>
        /// <param name="mode">The paramter mode.</param>
        /// <returns>The <paramref name="functionImport"/> (for composability).</returns>
        public static FunctionImport Parameter(this FunctionImport functionImport, string name, DataType dataType, FunctionParameterMode mode = FunctionParameterMode.In)
        {
            ExceptionUtilities.CheckArgumentNotNull(functionImport, "functionImport");
            ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(name, "localName");

            FunctionParameter parameter = new FunctionParameter(name, dataType, mode);

            functionImport.Parameters.Add(parameter);
            return(functionImport);
        }
Esempio n. 15
0
        /// <summary>
        /// Creates a new parameter for the specified function import.
        /// </summary>
        /// <param name="functionImport">The <see cref="FunctionImport"/> to add the parameter to.</param>
        /// <param name="name">The local name of the parameter.</param>
        /// <param name="returnType">The type of the function parameter.</param>
        /// <param name="mode">The paramter mode.</param>
        /// <returns>The <paramref name="functionImport"/> (for composability).</returns>
        public static FunctionImport ReturnType(this FunctionImport functionImport, DataType returnDataType, EntitySet entitySet = null)
        {
            ExceptionUtilities.CheckArgumentNotNull(functionImport, "functionImport");
            ExceptionUtilities.CheckArgumentNotNull(returnDataType, "returnDataType");

            FunctionImportReturnType returnType = new FunctionImportReturnType(returnDataType, entitySet);

            functionImport.ReturnTypes.Add(returnType);
            return(functionImport);
        }
Esempio n. 16
0
        /// <summary>
        /// Creates a new function import with the specified name.
        /// </summary>
        /// <param name="container">The <see cref="EntityContainer"/> to create the function import in.</param>
        /// <param name="localName">The name for the function import to create.</param>
        /// <returns>The newly created function import instance.</returns>
        public static FunctionImport FunctionImport(this EntityContainer container, string localName)
        {
            ExceptionUtilities.CheckArgumentNotNull(container, "container");
            ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(localName, "localName");

            FunctionImport functionImport = new FunctionImport(localName);

            container.Add(functionImport);
            return(functionImport);
        }
 protected override void ProcessPreReqCommands()
 {
     if (_createFuncImpCmdId != null)
     {
         var createFuncImpCmd = GetPreReqCommand(_createFuncImpCmdId) as CreateFunctionImportCommand;
         if (createFuncImpCmd != null)
         {
             FunctionImport = createFuncImpCmd.FunctionImport;
         }
     }
 }
Esempio n. 18
0
 protected override void ProcessPreReqCommands()
 {
     if (_createFuncImpCmdId != null)
     {
         var createFuncImpCmd = GetPreReqCommand(_createFuncImpCmdId) as CreateFunctionImportCommand;
         if (createFuncImpCmd != null)
         {
             FunctionImport = createFuncImpCmd.FunctionImport;
         }
     }
 }
        /// <summary>
        /// Initializes a new instance of the QueryFunctionImportCallExpression class.
        /// </summary>
        /// <param name="resultType">The function result type.</param>
        /// <param name="functionImport">The function to call.</param>
        /// <param name="isRoot">The value indicating whether it's a root query.</param>
        /// <param name="arguments">Arguments for the function call.</param>
        public QueryFunctionImportCallExpression(QueryType resultType, FunctionImport functionImport, bool isRoot, params QueryExpression[] arguments)
            : base(resultType)
        {
            ExceptionUtilities.CheckArgumentNotNull(functionImport, "functionImport");
            ExceptionUtilities.CheckArgumentNotNull(arguments, "arguments");
            ExceptionUtilities.Assert(functionImport.IsComposable, "Only composable function imports are allowed.");

            this.FunctionImport = functionImport;
            this.Arguments      = new ReadOnlyCollection <QueryExpression>(arguments.ToList());
            this.IsRoot         = isRoot;
        }
        /// <summary>
        /// Sets the expected function import for a top-level payload element.
        /// </summary>
        /// <param name="payloadElement">The payload element to set the expected function import for.</param>
        /// <param name="functionImport">The function import to set.</param>
        /// <returns>The <paramref name="payloadElement"/> after its expected function import was set.</returns>
        public static T ExpectedFunctionImport <T>(
            this T payloadElement,
            FunctionImport functionImport) where T : ODataPayloadElement
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");

            ExpectedTypeODataPayloadElementAnnotation annotation = AddExpectedTypeAnnotation(payloadElement);

            annotation.FunctionImport = functionImport;
            return(payloadElement);
        }
Esempio n. 21
0
 private static void NavigateToFunction(FunctionImport fi)
 {
     if (fi != null &&
         fi.FunctionImportMapping != null)
     {
         Debug.Assert(fi.FunctionImportMapping.FunctionImportName != null, "FunctionImportName is null");
         if (fi.FunctionImportMapping.FunctionImportName != null)
         {
             ExplorerNavigationHelper.NavigateTo(fi.FunctionImportMapping.FunctionImportName.Target);
         }
     }
 }
        private static void DeleteAllParameters(CommandProcessorContext cpc, FunctionImport fi)
        {
            IList <Parameter> parametersToDelete = new List <Parameter>();

            foreach (var parameter in fi.Parameters())
            {
                parametersToDelete.Add(parameter);
            }
            foreach (var parameter in parametersToDelete)
            {
                DeleteEFElementCommand.DeleteInTransaction(cpc, parameter);
            }
        }
Esempio n. 23
0
        // <summary>
        //     Launch edit function import dialog box.
        // </summary>
        public void EditFunctionImport(FunctionImport functionImport)
        {
            Debug.Assert(functionImport != null, "The functionImport passed in to EditFunctionImport is null.");
            if (null == functionImport)
            {
                return;
            }

            var artifact = functionImport.Artifact;

            Debug.Assert(artifact != null, "There is no artifact in the passed in functionImport.");
            if (null == artifact)
            {
                return;
            }

            var cModel = artifact.ConceptualModel();

            Debug.Assert(
                cModel != null, "There is no corresponding model item for the EDM Explorer's conceptual entity model representation.");
            if (null == cModel)
            {
                return;
            }

            var sModel = artifact.StorageModel();

            Debug.Assert(sModel != null, "There is no corresponding model item for the EDM Explorer's storage entity model representation");
            if (null == sModel)
            {
                return;
            }

            var cContainer = cModel.FirstEntityContainer as ConceptualEntityContainer;

            Debug.Assert(cContainer != null, "There is no conceptual entity container in the conceptual entity model");
            if (null == cContainer)
            {
                return;
            }

            EntityDesignViewModelHelper.EditFunctionImport(
                ViewModel.EditingContext,
                functionImport,
                sModel,
                cModel,
                cContainer,
                GetFunctionImportReturnType(cModel, functionImport),
                EfiTransactionOriginator.ExplorerWindowOriginatorId);
        }
Esempio n. 24
0
        /// <summary>
        /// Build a test model shared across several tests.
        /// </summary>
        /// <param name="addAnnotations">true if the annotations should be added upon construction; otherwise false.</param>
        /// <returns>Returns the test model.</returns>
        public static EntityModelSchema BuildODataAnnotationTestModel(bool addAnnotations)
        {
            // The metadata model with OData-specific annotations
            // - default entity container annotation
            // - HasStream annotation on entity type
            // - MimeType annotation on primitive property
            // - MimeType annotation on service operation
            EntityModelSchema model = new EntityModelSchema().MinimumVersion(ODataVersion.V4);

            ComplexType addressType = model.ComplexType("Address")
                                      .Property("Street", EdmDataTypes.String().Nullable())
                                      .Property("Zip", EdmDataTypes.Int32);

            if (addAnnotations)
            {
                addressType.Properties.Where(p => p.Name == "Zip").Single().MimeType("text/plain");
            }

            EntityType personType = model.EntityType("PersonType")
                                    .KeyProperty("Id", EdmDataTypes.Int32)
                                    .Property("Name", EdmDataTypes.String())
                                    .Property("Address", DataTypes.ComplexType.WithDefinition(addressType))
                                    .StreamProperty("Picture")
                                    .DefaultStream();

            if (addAnnotations)
            {
                personType.Properties.Where(p => p.Name == "Name").Single().MimeType("text/plain");
            }

            model.Fixup();

            // set the default container
            EntityContainer container = model.EntityContainers.Single();

            model.EntitySet("People", personType);

            // NOTE: Function import parameters and return types must be nullable as per current CSDL spec
            FunctionImport serviceOp = container.FunctionImport("ServiceOperation1")
                                       .Parameter("a", EdmDataTypes.Int32.Nullable())
                                       .Parameter("b", EdmDataTypes.String().Nullable())
                                       .ReturnType(EdmDataTypes.Int32.Nullable());

            if (addAnnotations)
            {
                serviceOp.MimeType("img/jpeg");
            }

            return(model);
        }
Esempio n. 25
0
        internal static ICollection <DeleteEFElementCommand> GetDeleteCommand(FunctionImport functionImport)
        {
            // try to locate a FunctionImportMapping for this import
            var commands = new List <DeleteEFElementCommand>();
            var functionImportMappings = functionImport.GetAntiDependenciesOfType <FunctionImportMapping>();

            foreach (var fim in functionImportMappings)
            {
                if (fim.FunctionImportName.Target == functionImport)
                {
                    commands.Add(new DeleteFunctionImportMappingCommand(fim));
                }
            }

            return(commands);
        }
        /// <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>();
        }
Esempio n. 27
0
        /// <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>();
        }
        /// <summary>
        /// Constructs a new function binding.
        /// </summary>
        /// <param name="import">The function import of the binding.</param>
        /// <param name="method">The method the import is bound to.</param>
        public FunctionBinding(FunctionImport import, MethodInfo method)
        {
            if (import is null)
            {
                throw new ArgumentNullException(nameof(import));
            }

            if (method is null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            Import = import;
            Method = method;

            Validate();
        }
Esempio n. 29
0
        /// <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);
        }
        /// <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);
        }
Esempio n. 31
0
        private XElement GenerateFunctionImport(XNamespace xmlNamespace, FunctionImport functionImport)
        {
            MethodAccessModifierAnnotation annotation = functionImport.Annotations.OfType <MethodAccessModifierAnnotation>().SingleOrDefault();
            EntitySetPathAnnotation        entitySetPathAnnotation = functionImport.Annotations.OfType <EntitySetPathAnnotation>().SingleOrDefault();

            return(new XElement(
                       xmlNamespace + "FunctionImport",
                       new XAttribute("Name", functionImport.Name),
                       this.GenerateDocumentation(xmlNamespace, functionImport),
                       this.CsdlDataTypeGenerator.GenerateReturnTypeForFunctionImport(functionImport.ReturnTypes, xmlNamespace),
                       functionImport.IsComposable ? new XAttribute("IsComposable", true) : null,
                       functionImport.IsSideEffecting ? null : new XAttribute("IsSideEffecting", false),
                       functionImport.IsBindable ? new XAttribute("IsBindable", true) : null,
                       entitySetPathAnnotation != null ? new XAttribute("EntitySetPath", entitySetPathAnnotation.EntitySetPath) : null,
                       this.GenerateFunctionImportParameters(functionImport.Parameters, xmlNamespace),
                       this.GenerateAnnotations(xmlNamespace, functionImport),
                       GenerateMethodAccessModifier(annotation)));
        }
        internal static bool CanEditMappingsForFunctionImport(FunctionImport fi, ref string errorMessage)
        {
            // make sure that we have a FunctionImportMapping defined
            if (fi.FunctionImportMapping == null)
            {
                errorMessage = Resources.MappingDetails_ErrMslCantFindFunctionImportMapping;
                return(false);
            }

            // make sure that there we can find mapped s-side Function
            if (fi.Function == null)
            {
                errorMessage = Resources.MappingDetails_ErrMslCantFindMappedFunction;
                return(false);
            }

            return(true);
        }
        internal static void UpdateFunctionImportParameters(
            CommandProcessorContext cpc, FunctionImport fi, IEnumerable <ParameterDefinition> parameterDefinitions)
        {
            DeleteAllParameters(cpc, fi);

            if (parameterDefinitions != null)
            {
                foreach (var definition in parameterDefinitions)
                {
                    var conceptualFunctionParam = new Parameter(fi, null);
                    conceptualFunctionParam.LocalName.Value = definition.Name;
                    conceptualFunctionParam.Mode.Value      = definition.Mode;
                    conceptualFunctionParam.Type.Value      = definition.Type;

                    fi.AddParameter(conceptualFunctionParam);
                    XmlModelHelper.NormalizeAndResolve(conceptualFunctionParam);
                }
            }
        }
Esempio n. 34
0
        // <summary>
        //     Calls a validation method to check if this association's MSL is editable by the designer
        // </summary>
        private bool CanEditMappingsForFunctionImport(FunctionImport fi)
        {
            var errorMessage = string.Empty;

            // check whether we should lit up the function import mapping.
            if (EdmFeatureManager.GetFunctionImportMappingFeatureState(fi.Artifact.SchemaVersion).IsEnabled() == false)
            {
                SetWatermarkInfo(Resources.MappingDetails_ErrMappingNotSupported);
                return(false);
            }
            else if (MappingViewModelHelper.CanEditMappingsForFunctionImport(fi, ref errorMessage))
            {
                return(true);
            }
            else
            {
                SetWatermarkInfo(string.Format(CultureInfo.CurrentCulture, Resources.MappingDetails_ErrMslGeneral, errorMessage));
                return(false);
            }
        }
        private FunctionImport ConvertToTaupoFunctionImport(IEdmOperationImport edmFunctionImport)
        {
            var taupoFunctionImport      = new FunctionImport(edmFunctionImport.Name);
            var functionImportReturnType = new FunctionImportReturnType();
            var addReturnType            = false;

            if (edmFunctionImport.EntitySet != null)
            {
                IEdmEntitySet entitySet;
                if (edmFunctionImport.TryGetStaticEntitySet(out entitySet))
                {
                    functionImportReturnType.EntitySet = new EntitySetReference(entitySet.Name);
                    addReturnType = true;
                }
                else
                {
                    throw new NotSupportedException("Function import with entity set path is not supported.");
                }
            }

            if (edmFunctionImport.Operation.ReturnType != null)
            {
                functionImportReturnType.DataType = this.ConvertToTaupoDataType(edmFunctionImport.Operation.ReturnType);
                addReturnType = true;
            }

            if (addReturnType)
            {
                taupoFunctionImport.Add(functionImportReturnType);
            }

            foreach (var edmFunctionParameter in edmFunctionImport.Operation.Parameters)
            {
                FunctionParameter taupoFunctionParameter = this.ConvertToTaupoFunctionParameter(edmFunctionParameter);
                taupoFunctionImport.Parameters.Add(taupoFunctionParameter);
            }

            this.ConvertAnnotationsIntoTaupo(edmFunctionImport, taupoFunctionImport);
            return(taupoFunctionImport);
        }
 internal void AddFunctionImport(FunctionImport fi)
 {
     _functionImports.Add(fi);
 }
 public ExplorerFunctionImport(EditingContext context, FunctionImport functionImport, ExplorerEFElement parent)
     : base(context, functionImport, parent)
 {
     // do nothing
 }
 internal static void ValidateFunctionImport(FunctionImport functionImport)
 {
     ValidateEFElement(functionImport);
 }
        protected override void InvokeInternal(CommandProcessorContext cpc)
        {
            // safety check, this should never be hit
            if (Container == null
                || (Function == null && ParameterDefinitions == null)
                || ReturnSingleType == null)
            {
                throw new InvalidOperationException(
                    "InvokeInternal is called when Container or Function or ParameterDefinitions or ReturnSingleType is null");
            }

            _fi = new FunctionImport(Container, null);
            _fi.LocalName.Value = FunctionImportName;

            // if we are using a high enough EDMX schema version then set IsComposable attribute
            if (EdmFeatureManager.GetComposableFunctionImportFeatureState(_fi.Artifact.SchemaVersion).IsEnabled())
            {
                // if Function.IsComposable is true set _fi.IsComposable to true also, but if it's false then
                // leave _fi.IsComposable unset which is equivalent to false
                if (Function.IsComposable.Value)
                {
                    _fi.IsComposable.Value = BoolOrNone.TrueValue;
                }
            }

            // if the return type is an EntityType, set the EntitySet attribute to
            // that EntityType's EntitySet. For other functions, don't set
            // the EntitySet.
            var returnSingleTypeString = ReturnSingleType as string;
            var returnSingleTypeComplexType = ReturnSingleType as ComplexType;
            var returnSingleTypeEntity = ReturnSingleType as EntityType;

            Debug.Assert(
                returnSingleTypeString != null || returnSingleTypeComplexType != null || returnSingleTypeEntity != null,
                "Return Type for function import must be of type string or ComplexType or EntityType");

            if (returnSingleTypeString != null)
            {
                // make sure that this is a primitive type or a complex type and build a "Collection()" around it.
                if (returnSingleTypeString != Tools.XmlDesignerBase.Resources.NoneDisplayValueUsedForUX)
                {
                    var edmPrimitiveTypes = ModelHelper.AllPrimitiveTypes(_fi.Artifact.SchemaVersion);
                    if (!edmPrimitiveTypes.Contains(returnSingleTypeString))
                    {
                        var msg = string.Format(CultureInfo.CurrentCulture, Resources.INVALID_FORMAT, returnSingleTypeString);
                        throw new CommandValidationFailedException(msg);
                    }

                    _fi.ReturnTypeAsPrimitiveType.Value = String.Format(
                        CultureInfo.InvariantCulture, FunctionImport.CollectionFormat, returnSingleTypeString);
                }
            }
            else if (returnSingleTypeComplexType != null)
            {
                var complexTypes = _fi.Artifact.ConceptualModel().ComplexTypes();
                if (!complexTypes.Contains(returnSingleTypeComplexType))
                {
                    var msg = string.Format(
                        CultureInfo.CurrentCulture, Resources.INVALID_FORMAT, returnSingleTypeComplexType.NormalizedNameExternal);
                    throw new CommandValidationFailedException(msg);
                }

                _fi.ReturnTypeAsComplexType.SetRefName(returnSingleTypeComplexType);
            }
            else if (returnSingleTypeEntity != null)
            {
                _fi.EntitySet.SetRefName(returnSingleTypeEntity.EntitySet);
                _fi.ReturnTypeAsEntityType.SetRefName(returnSingleTypeEntity);
            }

            Container.AddFunctionImport(_fi);
            XmlModelHelper.NormalizeAndResolve(_fi);

            if (ParameterDefinitions != null)
            {
                UpdateFunctionImportParameters(cpc, _fi, ParameterDefinitions);
            }
            if (Function != null)
            {
                UpdateFunctionImportParameters(cpc, _fi, Function);
            }
        }
        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));
        }
        internal static void UpdateFunctionImportParameters(CommandProcessorContext cpc, FunctionImport fi, Function function)
        {
            DeleteAllParameters(cpc, fi);

            if (function != null
                && function.Parameters().Count > 0)
            {
                var storeTypeNameToStoreTypeMap = function.EntityModel.StoreTypeNameToStoreTypeMap;
                Debug.Assert(
                    storeTypeNameToStoreTypeMap != null, "StoreTypeName to StoreType map should not be null. Not updating function import");
                if (storeTypeNameToStoreTypeMap != null)
                {
                    IDictionary<string, string> storeToEdmPrimitiveMap = storeTypeNameToStoreTypeMap.ToDictionary(
                        kvp => kvp.Key, kvp => kvp.Value.GetEdmPrimitiveType().Name);

                    // Parameter EFElement conveniently can be used in both the C-Side and S-Side.
                    foreach (var storageFunctionParam in function.Parameters())
                    {
                        var conceptualFunctionParam = new Parameter(fi, null);

                        conceptualFunctionParam.LocalName.Value = storageFunctionParam.LocalName.Value;
                        conceptualFunctionParam.Mode.Value = storageFunctionParam.Mode.Value;

                        string conceptualFunctionParamValue;
                        if (storeToEdmPrimitiveMap.TryGetValue(storageFunctionParam.Type.Value, out conceptualFunctionParamValue))
                        {
                            conceptualFunctionParam.Type.Value = conceptualFunctionParamValue;
                        }
                        else
                        {
                            conceptualFunctionParam.Type.Value = storageFunctionParam.Type.Value;
                        }

                        fi.AddParameter(conceptualFunctionParam);
                        XmlModelHelper.NormalizeAndResolve(conceptualFunctionParam);
                    }
                }
            }
        }
        // Method is moved from EntityDesignViewModelHelper. 
        internal static Object GetFunctionImportReturnType(ConceptualEntityModel cModel, FunctionImport functionImport)
        {
            object value = null;
            if (functionImport.IsReturnTypeEntityType)
            {
                if (functionImport.ReturnTypeAsEntityType.Status == BindingStatus.Known)
                {
                    value = functionImport.ReturnTypeAsEntityType.Target.NormalizedNameExternal;
                }
                else
                {
                    value = ModelHelper.UnwrapCollectionAroundFunctionImportReturnType(functionImport.ReturnTypeAsEntityType.RefName, true);
                }
            }
            else if (functionImport.IsReturnTypeComplexType)
            {
                if (functionImport.ReturnTypeAsComplexType.Status == BindingStatus.Known)
                {
                    value = functionImport.ReturnTypeAsComplexType.Target.NormalizedNameExternal;
                }
                else
                {
                    value = ModelHelper.UnwrapCollectionAroundFunctionImportReturnType(functionImport.ReturnTypeAsComplexType.RefName, true);
                }
            }
            else
            {
                value = ModelHelper.UnwrapCollectionAroundFunctionImportReturnType(functionImport.ReturnTypeAsPrimitiveType.Value);
            }

            var selectedElement = ModelHelper.FindComplexTypeEntityTypeOrPrimitiveTypeForFunctionImportReturnType(cModel, value as string);
            return selectedElement;
        }
        internal static bool CanEditMappingsForFunctionImport(FunctionImport fi, ref string errorMessage)
        {
            // make sure that we have a FunctionImportMapping defined
            if (fi.FunctionImportMapping == null)
            {
                errorMessage = Resources.MappingDetails_ErrMslCantFindFunctionImportMapping;
                return false;
            }

            // make sure that there we can find mapped s-side Function
            if (fi.Function == null)
            {
                errorMessage = Resources.MappingDetails_ErrMslCantFindMappedFunction;
                return false;
            }

            return true;
        }
 internal override bool ParseSingleElement(ICollection<XName> unprocessedElements, XElement elem)
 {
     if (elem.Name.LocalName == EntitySet.ElementName)
     {
         EntitySet es = new ConceptualEntitySet(this, elem);
         AddEntitySet(es);
         es.Parse(unprocessedElements);
     }
     else if (elem.Name.LocalName == FunctionImport.ElementName)
     {
         var fi = new FunctionImport(this, elem);
         _functionImports.Add(fi);
         fi.Parse(unprocessedElements);
     }
     else
     {
         return base.ParseSingleElement(unprocessedElements, elem);
     }
     return true;
 }
 /// <summary>
 ///     Delete the passed in function
 /// </summary>
 /// <param name="fim"></param>
 internal DeleteFunctionImportCommand(FunctionImport fi)
     : base(fi)
 {
     CommandValidation.ValidateFunctionImport(fi);
 }
 private static void NavigateToFunction(FunctionImport fi)
 {
     if (fi != null
         && fi.FunctionImportMapping != null)
     {
         Debug.Assert(fi.FunctionImportMapping.FunctionImportName != null, "FunctionImportName is null");
         if (fi.FunctionImportMapping.FunctionImportName != null)
         {
             ExplorerNavigationHelper.NavigateTo(fi.FunctionImportMapping.FunctionImportName.Target);
         }
     }
 }
 // <summary>
 //     Calls a validation method to check if this association's MSL is editable by the designer
 // </summary>
 private bool CanEditMappingsForFunctionImport(FunctionImport fi)
 {
     var errorMessage = string.Empty;
     // check whether we should lit up the function import mapping.
     if (EdmFeatureManager.GetFunctionImportMappingFeatureState(fi.Artifact.SchemaVersion).IsEnabled() == false)
     {
         SetWatermarkInfo(Resources.MappingDetails_ErrMappingNotSupported);
         return false;
     }
     else if (MappingViewModelHelper.CanEditMappingsForFunctionImport(fi, ref errorMessage))
     {
         return true;
     }
     else
     {
         SetWatermarkInfo(string.Format(CultureInfo.CurrentCulture, Resources.MappingDetails_ErrMslGeneral, errorMessage));
         return false;
     }
 }
        internal static ICollection<DeleteEFElementCommand> GetDeleteCommand(FunctionImport functionImport)
        {
            // try to locate a FunctionImportMapping for this import
            var commands = new List<DeleteEFElementCommand>();
            var functionImportMappings = functionImport.GetAntiDependenciesOfType<FunctionImportMapping>();
            foreach (var fim in functionImportMappings)
            {
                if (fim.FunctionImportName.Target == functionImport)
                {
                    commands.Add(new DeleteFunctionImportMappingCommand(fim));
                }
            }

            return commands;
        }
        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();
            }
        }
        // <summary>
        //     Launch edit function import dialog box.
        // </summary>
        public void EditFunctionImport(FunctionImport functionImport)
        {
            Debug.Assert(functionImport != null, "The functionImport passed in to EditFunctionImport is null.");
            if (null == functionImport)
            {
                return;
            }

            var artifact = functionImport.Artifact;
            Debug.Assert(artifact != null, "There is no artifact in the passed in functionImport.");
            if (null == artifact)
            {
                return;
            }

            var cModel = artifact.ConceptualModel();
            Debug.Assert(
                cModel != null, "There is no corresponding model item for the EDM Explorer's conceptual entity model representation.");
            if (null == cModel)
            {
                return;
            }

            var sModel = artifact.StorageModel();
            Debug.Assert(sModel != null, "There is no corresponding model item for the EDM Explorer's storage entity model representation");
            if (null == sModel)
            {
                return;
            }

            var cContainer = cModel.FirstEntityContainer as ConceptualEntityContainer;
            Debug.Assert(cContainer != null, "There is no conceptual entity container in the conceptual entity model");
            if (null == cContainer)
            {
                return;
            }

            EntityDesignViewModelHelper.EditFunctionImport(
                ViewModel.EditingContext,
                functionImport,
                sModel,
                cModel,
                cContainer,
                GetFunctionImportReturnType(cModel, functionImport),
                EfiTransactionOriginator.ExplorerWindowOriginatorId);
        }
        internal static void UpdateFunctionImportParameters(
            CommandProcessorContext cpc, FunctionImport fi, IEnumerable<ParameterDefinition> parameterDefinitions)
        {
            DeleteAllParameters(cpc, fi);

            if (parameterDefinitions != null)
            {
                foreach (var definition in parameterDefinitions)
                {
                    var conceptualFunctionParam = new Parameter(fi, null);
                    conceptualFunctionParam.LocalName.Value = definition.Name;
                    conceptualFunctionParam.Mode.Value = definition.Mode;
                    conceptualFunctionParam.Type.Value = definition.Type;

                    fi.AddParameter(conceptualFunctionParam);
                    XmlModelHelper.NormalizeAndResolve(conceptualFunctionParam);
                }
            }
        }
 private ExplorerFunctionImport AddFunctionImport(FunctionImport funcImport)
 {
     var explorerFuncImport =
         ModelToExplorerModelXRef.GetNew(_context, funcImport, this, typeof(ExplorerFunctionImport)) as ExplorerFunctionImport;
     _functionImports.Insert(explorerFuncImport);
     return explorerFuncImport;
 }
 private static void DeleteAllParameters(CommandProcessorContext cpc, FunctionImport fi)
 {
     IList<Parameter> parametersToDelete = new List<Parameter>();
     foreach (var parameter in fi.Parameters())
     {
         parametersToDelete.Add(parameter);
     }
     foreach (var parameter in parametersToDelete)
     {
         DeleteEFElementCommand.DeleteInTransaction(cpc, parameter);
     }
 }
        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;
            }
        }