private void CreateFunctionMappingComplexTypeMapping(CommandEntity entity, FunctionImportMapping importMapping)
        {
            //<ResultMapping>
            //  <ComplexTypeMapping TypeName="PetShopModel.GetCategoryById_Result">
            string entityName = String.Concat(entity.Name, "Result");
            var    mapping    = importMapping.ResultMapping != null && importMapping.ResultMapping.ComplexTypeMappings != null
                              ? importMapping.ResultMapping.ComplexTypeMappings.FirstOrDefault()
                              : null;

            if (mapping == null)
            {
                importMapping.ResultMapping = new FunctionImportMappingResultMapping()
                {
                    ComplexTypeMappings = new List <FunctionImportComplexTypeMapping>()
                };

                mapping = new FunctionImportComplexTypeMapping()
                {
                    TypeName = String.Concat(ConceptualSchema.Namespace, ".", entityName)
                };
                importMapping.ResultMapping.ComplexTypeMappings.Add(mapping);
            }
            else if (!String.IsNullOrEmpty(mapping.TypeName))
            {
                entityName = mapping.TypeName.Replace("IsTypeOf(", "").Replace(String.Format("{0}.", ConceptualSchema.Namespace), "").Replace(")", "");
                entityName = entityName.Equals(entity.Name, StringComparison.OrdinalIgnoreCase) ? entity.Name : entityName;
            }

            if (ConceptualSchema.ComplexTypes.Count(c => c.Name.Equals(entityName, StringComparison.OrdinalIgnoreCase)) == 0)
            {
                entityName = String.Concat(entity.Name, "Result");
            }

            // Check for inheritance.
            mapping.TypeName = String.Format("{0}.{1}", ConceptualSchema.Namespace, entityName);

            _mappingEntityNames.Add(entity.EntityKey(), importMapping.FunctionImportName);
            _mappingEntityNames.Add(entity.EntityKey() + "complex", entityName);

            //<ComplexTypeMapping TypeName="PetShopModel.GetCategoryById_Result">
            //  <ScalarProperty Name="CategoryId" ColumnName="CategoryId" />
            //  <ScalarProperty Name="Name" ColumnName="Name" />
            //  <ScalarProperty Name="Description" ColumnName="Descn" />
            //</ComplexTypeMapping>
            MergeScalarProperties(mapping, entity);
        }
        private void CreateFunctionMappingComplexTypeMapping(CommandEntity entity, FunctionImportMapping importMapping)
        {
            //<ResultMapping>
            //  <ComplexTypeMapping TypeName="PetShopModel.GetCategoryById_Result">
            string entityName = String.Concat(entity.Name, "Result");
            var mapping = importMapping.ResultMapping != null && importMapping.ResultMapping.ComplexTypeMappings != null
                              ? importMapping.ResultMapping.ComplexTypeMappings.FirstOrDefault()
                              : null;

            if (mapping == null)
            {
                importMapping.ResultMapping = new FunctionImportMappingResultMapping()
                                                  {
                                                      ComplexTypeMappings = new List<FunctionImportComplexTypeMapping>()
                                                  };

                mapping = new FunctionImportComplexTypeMapping() { TypeName = String.Concat(ConceptualSchema.Namespace, ".", entityName) };
                importMapping.ResultMapping.ComplexTypeMappings.Add(mapping);
            }
            else if (!String.IsNullOrEmpty(mapping.TypeName))
            {
                entityName = mapping.TypeName.Replace("IsTypeOf(", "").Replace(String.Format("{0}.", ConceptualSchema.Namespace), "").Replace(")", "");
                entityName = entityName.Equals(entity.Name, StringComparison.OrdinalIgnoreCase) ? entity.Name : entityName;
            }

            if(ConceptualSchema.ComplexTypes.Count(c => c.Name.Equals(entityName, StringComparison.OrdinalIgnoreCase)) == 0)
                entityName = String.Concat(entity.Name, "Result");

            // Check for inheritance.
            mapping.TypeName = String.Format("{0}.{1}", ConceptualSchema.Namespace, entityName);

            _mappingEntityNames.Add(entity.EntityKey(), importMapping.FunctionImportName);
            _mappingEntityNames.Add(entity.EntityKey() + "complex", entityName);

            //<ComplexTypeMapping TypeName="PetShopModel.GetCategoryById_Result">
            //  <ScalarProperty Name="CategoryId" ColumnName="CategoryId" />
            //  <ScalarProperty Name="Name" ColumnName="Name" />
            //  <ScalarProperty Name="Description" ColumnName="Descn" />
            //</ComplexTypeMapping>
            MergeScalarProperties(mapping, entity);
        }
        private void CreateConceptualFunctionEntity(CommandEntity entity)
        {
            // Check to see if this has already been processed.
            if (entity.IsFunction || _conceptualFunctions.Contains(ResolveEntityMappedName(entity.EntityKey(), entity.Name)) || !Configuration.Instance.IncludeFunctions) return;

            //<FunctionImport Name="GetCategoryById">
            //    <Parameter Name="ID" Mode="In" Type="String" />
            //</FunctionImport>

            //<FunctionImport Name="GetCategoryById" ReturnType="Collection(PetShopModel.GetCategoryById_Result1)">
            //   <Parameter Name="ID" Mode="In" Type="String" />
            //</FunctionImport>

            //  <FunctionImport Name="GetCategoryById" EntitySet="Categories" ReturnType="Collection(PetShopModel.Category)">
            //    <Parameter Name="ID" Mode="In" Type="String" />
            //  </FunctionImport>

            //  <FunctionImport Name="GetCategoryById" ReturnType="Collection(Int32)">
            //    <Parameter Name="ID" Mode="In" Type="String" />
            //  </FunctionImport>
            #region Validate the Function exists

            bool exists = true;
            var function = ConceptualSchemaEntityContainer.FunctionImports.Where(f =>
                entity.Name.Equals(f.Name, StringComparison.OrdinalIgnoreCase) ||
                entity.EntityKeyName.Equals(f.Name, StringComparison.OrdinalIgnoreCase) ||
                (!String.IsNullOrEmpty(f.EntitySet) && entity.EntityKeyName.Equals(f.EntitySet, StringComparison.OrdinalIgnoreCase))).FirstOrDefault();

            if (function == null)
            {
                exists = false;
                function = new EntityContainer.FunctionImportLocalType
                               {
                                   Name = ResolveEntityMappedName(entity.EntityKey(), entity.Name)
                               };

                ConceptualSchemaEntityContainer.FunctionImports.Add(function);
            }

            #endregion

            //http://msdn.microsoft.com/en-us/library/bb738614.aspx
            function.Name = ResolveEntityMappedName(entity.EntityKey(), entity.Name);
            var entitySetName = entity.IsAssociated
                                    ? ResolveEntityMappedName(entity.AssociatedEntity.EntityKey(), entity.AssociatedEntity.Name)
                                    : ResolveEntityMappedName(entity.EntityKey(), entity.Name);
            if(exists)
            {
                var type = function.ReturnType != null ? function.ReturnType.ToString().Replace("Collection(", String.Empty).Replace(")", String.Empty).Trim() : String.Empty;
                var complexTypeName = NamingConventions.PropertyName(type.Replace(ConceptualSchema.Namespace + ".", String.Empty));
                if (entity.IsStronglyTypedAssociatedEntity)
                {
                    function.EntitySet = entitySetName;
                    function.ReturnType = String.Format("Collection({0}.{1})", ConceptualSchema.Namespace, entitySetName);
                }
                else if (function.IsComplexType(ConceptualSchema.Namespace) && ConceptualSchema.ComplexTypes.Exists(complexTypeName) && entity.Properties.Count > 0)
                {
                    function.EntitySet = null;
                    function.ReturnType = String.Format("Collection({0}.{1})", ConceptualSchema.Namespace, complexTypeName);
                    CreateConceptualComplexType(entity, complexTypeName);
                }
                else if (!String.IsNullOrEmpty(type) && !SystemTypeMapper.EfConceptualTypeToSystemType.ContainsKey(type))
                {
                    function.ReturnType = null;
                    function.EntitySet = null;
                }
            }
            else if (entity.IsStronglyTypedAssociatedEntity)
            {
                function.EntitySet = entitySetName;
                function.ReturnType = String.Format("Collection({0}.{1})", ConceptualSchema.Namespace, entitySetName);
            }
            else if(entity.Properties.Count > 0)
            {
                function.ReturnType = null;
                //By default create a new ComplexType for a procedure's resultset if it contains more a column in the result set.
                function.ReturnType = String.Format("Collection({0}.{1}Result)", ConceptualSchema.Namespace, ResolveEntityMappedName(entity.EntityKey(), entity.Name));
                CreateConceptualComplexType(entity);
            }
            else
            {
                function.ReturnType = null;
                function.EntitySet = null;
            }

            //<Parameter Name="ApplicationName" Type="nvarchar" Mode="In" />
            //<Parameter Name="ApplicationId" Type="uniqueidentifier" Mode="InOut" />
            #region Process Parameters

            if (entity.SearchCriteria != null && entity.SearchCriteria.Count > 0)
            {
                #region Remove extra properties values.

                var properties = from property in function.Parameters
                                 where !(from prop in entity.SearchCriteria[0].Properties select prop.KeyName).Contains(property.Name) || property.Name.Equals("RETURN_VALUE", StringComparison.OrdinalIgnoreCase)
                                 select property;

                // Remove all of the key properties that don't exist in the table entity.
                foreach (var property in properties)
                {
                    function.Parameters.Remove(property);
                }

                #endregion

                foreach (CommandParameter property in entity.SearchCriteria[0].Properties)
                {
                    if (property.KeyName.Equals("RETURN_VALUE", StringComparison.OrdinalIgnoreCase)) continue;

                    var parameter = function.Parameters.Where(p => property.KeyName.Equals(p.Name, StringComparison.OrdinalIgnoreCase) || property.Name.Equals(p.Name, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                    if (parameter == null)
                    {
                        parameter = new FunctionImportParameter() { Name = property.KeyName };
                        function.Parameters.Add(parameter);
                    }

                    //http://msdn.microsoft.com/en-us/library/ee705451.aspx
                    parameter.Name = property.KeyName;
                    parameter.Mode = property.ParameterDirection == ParameterDirection.Input ? "In" : property.ParameterDirection == ParameterDirection.InputOutput ? "InOut" : "Out";
                    parameter.Type = GetSystemType(property);
                }
            }
            else
            {
                function.Parameters.Clear();
            }

            #endregion

            _conceptualFunctions.Add(ResolveEntityMappedName(entity.EntityKey(), entity.Name));
        }