private void RegisterGeomIntersectsFunction()
        {
            EdmFunction edmFunction;
            var         edmReturnType = EdmTypeMap.GetEdmPrimitiveType(typeof(bool));

            edmFunction = new EdmFunction("geom", "intersects", new EdmPrimitiveTypeReference(edmReturnType, false), false, null, true);
            AddElement(edmFunction);
            var edmParameterType = EdmTypeMap.GetEdmPrimitiveType(typeof(Geometry));

            edmFunction.AddParameter("geometry1", new EdmPrimitiveTypeReference(edmParameterType, false));
            edmFunction.AddParameter("geometry2", new EdmPrimitiveTypeReference(edmParameterType, false));
        }
        internal void AddUserFunction(Function function)
        {
            if (function is Action)
            {
                AddAction(function as Action);
                return;
            }

            EdmFunction        edmFunction;
            EdmEntityContainer entityContainer  = (EdmEntityContainer)EntityContainer;
            IEdmTypeReference  edmTypeReference = GetNotEntityTypeReference(function.ReturnType);

            if (edmTypeReference == null)
            {
                edmTypeReference = GetCollectionNotEntityTypeReference(function.ReturnType);
            }

            if (edmTypeReference != null)
            {
                edmFunction = new EdmFunction(DefaultNamespace, function.Name, edmTypeReference, false, null, false);
                entityContainer.AddFunctionImport(edmFunction);
            }
            else
            {
                IEdmTypeReference returnEdmTypeReference = GetEdmTypeReference(function.ReturnType, out IEdmEntityType returnEntityType, out bool isCollection);
                if (returnEntityType == null)
                {
                    throw new ArgumentNullException("Тип возвращаемого результата пользовательской функции не найден в модели OData.");
                }

                edmFunction = new EdmFunction(DefaultNamespace, function.Name, returnEdmTypeReference, true, null, true);
                edmFunction.AddParameter("bindingParameter", returnEdmTypeReference);
                entityContainer.AddFunctionImport(function.Name, edmFunction, new EdmEntitySetReferenceExpression(GetEdmEntitySet(returnEntityType)), true);
            }

            AddElement(edmFunction);
            foreach (var parameter in function.ParametersTypes.Keys)
            {
                Type         paramType        = function.ParametersTypes[parameter];
                IEdmEnumType enumType         = GetEdmEnumType(paramType);
                var          edmParameterType = EdmTypeMap.GetEdmPrimitiveType(paramType);
                if (edmParameterType != null)
                {
                    edmFunction.AddParameter(parameter, new EdmPrimitiveTypeReference(edmParameterType, false));
                }

                if (enumType != null)
                {
                    edmFunction.AddParameter(parameter, new EdmEnumTypeReference(enumType, false));
                }
            }
        }
        private void BuildOwnProperties(EdmEntityType edmEntityType, Type dataObjectType)
        {
            var settings        = _metadata[dataObjectType];
            var keyPropertyType = settings.KeyType == null ? null : EdmTypeMap.GetEdmPrimitiveType(settings.KeyType);
            IEnumerable <PropertyInfo> ownProperties = settings.OwnProperties;

            foreach (var propertyInfo in ownProperties)
            {
                if (propertyInfo.Name == _metadata.KeyPropertyName && keyPropertyType != null)
                {
                    EdmStructuralProperty key = edmEntityType.AddStructuralProperty(propertyInfo.Name, keyPropertyType.PrimitiveKind);
                    edmEntityType.AddKeys(key);
                    continue;
                }

                Type propertyType = propertyInfo.PropertyType;
                if (propertyType.IsEnum)
                {
                    EdmEnumType edmEnumType;
                    if (!_registeredEnums.TryGetValue(propertyType, out edmEnumType))
                    {
                        edmEnumType = new EdmEnumType(propertyType.Namespace, propertyType.Name);

                        Array    enumValues = Enum.GetValues(propertyType);
                        string[] enumNames  = Enum.GetNames(propertyType);
                        for (int i = 0; i < enumNames.Length; i++)
                        {
                            int intValue = (int)enumValues.GetValue(i);
                            edmEnumType.AddMember(new EdmEnumMember(edmEnumType, enumNames[i], new EdmIntegerConstant(intValue)));
                        }

                        _registeredEnums.Add(propertyType, edmEnumType);
                        AddElement(edmEnumType);
                    }

                    EdmStructuralProperty edmProp = edmEntityType.AddStructuralProperty(GetEntityPropertName(propertyInfo), new EdmEnumTypeReference(edmEnumType, false));
                    this.SetAnnotationValue(edmProp, new ClrPropertyInfoAnnotation(propertyInfo));
                }

                IEdmPrimitiveType edmPrimitiveType = EdmTypeMap.GetEdmPrimitiveType(propertyType);
                if (edmPrimitiveType != null)
                {
                    EdmStructuralProperty edmProp = edmEntityType.AddStructuralProperty(GetEntityPropertName(propertyInfo), edmPrimitiveType.PrimitiveKind);
                    this.SetAnnotationValue(edmProp, new ClrPropertyInfoAnnotation(propertyInfo));
                }
            }
        }
        private IEdmTypeReference GetNotEntityTypeReference(Type clrType)
        {
            IEdmType edmType = EdmTypeMap.GetEdmPrimitiveType(clrType);

            if (edmType != null)
            {
                return(new EdmPrimitiveTypeReference(edmType as IEdmPrimitiveType, false));
            }

            edmType = GetEdmEnumType(clrType);
            if (edmType != null)
            {
                return(new EdmEnumTypeReference(edmType as IEdmEnumType, false));
            }

            return(null);
        }