Пример #1
0
        /// <summary>
        /// Finds the entity set that a navigation property targets.
        /// </summary>
        /// <param name="navigationProperty">The navigation property.</param>
        /// <param name="bindingPath">The binding path of the navigation property</param>
        /// <returns>The entity set that the navigation property targets</returns>
        public override IEdmNavigationSource FindNavigationTarget(IEdmNavigationProperty navigationProperty, IEdmPathExpression bindingPath)
        {
            // 7.4.1 expected the path to be prefixed with the path to the contained navigation source.
            // For backward compatibility, if the binding path received starts with the path to this contained resource,
            // we trim it off and then treat the remainder as the path to the target. This logic should be removed in
            // the next breaking change as it could be ambiguous in the case that the prefix of the path to the contained
            // source matches a valid path to the target of the contained source.
            if (bindingPath != null)
            {
                if (bindingPath.Path.Length > this.FullNavigationPath.Length && bindingPath.Path.StartsWith(this.FullNavigationPath, System.StringComparison.Ordinal))
                {
                    bindingPath = new EdmPathExpression(bindingPath.Path.Substring(this.FullNavigationPath.Length + 1));
                }
            }

            IEdmNavigationSource navigationTarget = base.FindNavigationTarget(navigationProperty, bindingPath);

            if (navigationTarget is IEdmUnknownEntitySet)
            {
                IEnumerable <string> segments = (bindingPath == null || string.IsNullOrEmpty(bindingPath.Path)) ? new string[] { navigationProperty.Name } : bindingPath.PathSegments;
                bindingPath = new EdmPathExpression(this.NavigationPath.PathSegments.Concat(segments));

                return(this.parentNavigationSource.FindNavigationTarget(navigationProperty, bindingPath));
            }

            return(navigationTarget);
        }
        private void BuildOperations(EdmModel model, string modelNamespace)
        {
            foreach (var operationMethodInfo in operationInfos)
            {
                // With this method, if return type is nullable type,it will get underlying type
                var returnType          = TypeHelper.GetUnderlyingTypeOrSelf(operationMethodInfo.Method.ReturnType);
                var returnTypeReference = returnType.GetReturnTypeReference(model);
                var isBound             = operationMethodInfo.IsBound;
                var bindingParameter    = operationMethodInfo.Method.GetParameters().FirstOrDefault();

                if (bindingParameter == null && isBound)
                {
                    // Ignore the method which is marked as bounded but no parameters
                    continue;
                }

                var namespaceName = GetNamespaceName(operationMethodInfo, modelNamespace);

                EdmOperation      operation = null;
                EdmPathExpression path      = null;
                if (isBound)
                {
                    // Unbound actions or functions should not have EntitySetPath attribute
                    path = BuildBoundOperationReturnTypePathExpression(returnTypeReference, bindingParameter);
                }

                if (operationMethodInfo.HasSideEffects)
                {
                    operation = new EdmAction(namespaceName, operationMethodInfo.Name, returnTypeReference, isBound, path);
                }
                else
                {
                    operation = new EdmFunction(namespaceName, operationMethodInfo.Name, returnTypeReference, isBound, path, operationMethodInfo.IsComposable);
                }

                BuildOperationParameters(operation, operationMethodInfo.Method, model);
                model.AddElement(operation);

                if (!isBound)
                {
                    // entitySetReferenceExpression refer to an entity set containing entities returned
                    // by this function/action import.
                    var entitySetExpression = BuildEntitySetExpression(
                        model, operationMethodInfo.EntitySet, returnTypeReference);
                    var entityContainer = model.EnsureEntityContainer(targetType);
                    if (operationMethodInfo.HasSideEffects)
                    {
                        entityContainer.AddActionImport(operation.Name, (EdmAction)operation, entitySetExpression);
                    }
                    else
                    {
                        entityContainer.AddFunctionImport(
                            operation.Name, (EdmFunction)operation, entitySetExpression);
                    }
                }
            }
        }