Example #1
0
 /// <summary>
 /// Constructs a KeyLookupNode.
 /// </summary>
 /// <param name="source">The collection that this key is referring to.</param>
 /// <param name="keyPropertyValues">List of the properties and their values that we use to look up our return value.</param>
 /// <exception cref="System.ArgumentNullException">Throws if the input source is null.</exception>
 public KeyLookupNode(EntityCollectionNode source, IEnumerable<KeyPropertyValue> keyPropertyValues)
 {
     ExceptionUtils.CheckArgumentNotNull(source, "source");
     this.source = source;
     this.navigationSource = source.NavigationSource;
     this.entityTypeReference = source.EntityItemType;
     this.keyPropertyValues = keyPropertyValues;
 }
Example #2
0
 /// <summary>
 /// Constructs a KeyLookupNode.
 /// </summary>
 /// <param name="source">The collection that this key is referring to.</param>
 /// <param name="keyPropertyValues">List of the properties and their values that we use to look up our return value.</param>
 /// <exception cref="System.ArgumentNullException">Throws if the input source is null.</exception>
 public KeyLookupNode(EntityCollectionNode source, IEnumerable <KeyPropertyValue> keyPropertyValues)
 {
     ExceptionUtils.CheckArgumentNotNull(source, "source");
     this.source              = source;
     this.navigationSource    = source.NavigationSource;
     this.entityTypeReference = source.EntityItemType;
     this.keyPropertyValues   = keyPropertyValues;
 }
 /// <summary>
 /// Creates a <see cref="EntityRangeVariable"/>.
 /// </summary>
 /// <param name="name"> The name of the associated any/all parameter (null if none)</param>
 /// <param name="entityType">The entity type of each item in the collection that this range variable iterates over.</param>
 /// <param name="navigationSource">The navigation source of the collection this node iterates over.</param>
 /// <exception cref="System.ArgumentNullException">Throws if the input name or entityType is null.</exception>
 public EntityRangeVariable(string name, IEdmEntityTypeReference entityType, IEdmNavigationSource navigationSource)
 {
     ExceptionUtils.CheckArgumentNotNull(name, "name");
     ExceptionUtils.CheckArgumentNotNull(entityType, "entityType");
     this.name = name;
     this.entityTypeReference  = entityType;
     this.entityCollectionNode = null;
     this.navigationSource     = navigationSource;
 }
 /// <summary>
 /// Creates a <see cref="EntityRangeVariable"/>.
 /// </summary>
 /// <param name="name"> The name of the associated any/all parameter (null if none)</param>
 /// <param name="entityType">The entity type of each item in the collection that this range variable iterates over.</param>
 /// <param name="navigationSource">The navigation source of the collection this node iterates over.</param>
 /// <exception cref="System.ArgumentNullException">Throws if the input name or entityType is null.</exception>
 public EntityRangeVariable(string name, IEdmEntityTypeReference entityType, IEdmNavigationSource navigationSource)
 {
     ExceptionUtils.CheckArgumentNotNull(name, "name");
     ExceptionUtils.CheckArgumentNotNull(entityType, "entityType");
     this.name = name;
     this.entityTypeReference = entityType;
     this.entityCollectionNode = null;
     this.navigationSource = navigationSource;
 }
Example #5
0
        /// <summary>
        /// Create a CollectionCastNode with the given source node and the given target type.
        /// </summary>
        /// <param name="source">Parent <see cref="CollectionNode"/> that is being cast.</param>
        /// <param name="entityType">Type to cast to.</param>
        /// <exception cref="System.ArgumentNullException">Throws if the input source or entityType are null.</exception>
        public EntityCollectionCastNode(EntityCollectionNode source, IEdmEntityType entityType)
        {
            ExceptionUtils.CheckArgumentNotNull(source, "source");
            ExceptionUtils.CheckArgumentNotNull(entityType, "entityType");
            this.source           = source;
            this.edmTypeReference = new EdmEntityTypeReference(entityType, false);
            this.navigationSource = source.NavigationSource;

            // creating a new collection type here because the type in the request is just the item type, there is no user-provided collection type.
            this.collectionTypeReference = EdmCoreModel.GetCollection(this.edmTypeReference);
        }
Example #6
0
        /// <summary>
        /// Tries to bind key values to a key lookup on a collection.
        /// </summary>
        /// <param name="collectionNode">Already bound collection node.</param>
        /// <param name="namedValues">The named value tokens to bind.</param>
        /// <param name="model">The model to be used.</param>
        /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param>
        /// <param name="keyLookupNode">The bound key lookup.</param>
        /// <returns>Returns true if binding succeeded.</returns>
        private bool TryBindToDeclaredAlternateKey(EntityCollectionNode collectionNode, IEnumerable<NamedValue> namedValues, IEdmModel model, IEdmEntityType collectionItemEntityType, out QueryNode keyLookupNode)
        {
            IEnumerable<IDictionary<string, IEdmProperty>> alternateKeys = model.GetAlternateKeysAnnotation(collectionItemEntityType);
            foreach (IDictionary<string, IEdmProperty> keys in alternateKeys)
            {
                if (TryBindToKeys(collectionNode, namedValues, model, collectionItemEntityType, keys, out keyLookupNode))
                {
                    return true;
                }
            }

            keyLookupNode = null;
            return false;
        }
Example #7
0
        /// <summary>
        /// Binds key values to a key lookup on a collection.
        /// </summary>
        /// <param name="collectionNode">Already bound collection node.</param>
        /// <param name="namedValues">The named value tokens to bind.</param>
        /// <param name="model">The model to be used.</param>
        /// <returns>The bound key lookup.</returns>
        internal QueryNode BindKeyValues(EntityCollectionNode collectionNode, IEnumerable<NamedValue> namedValues, IEdmModel model)
        {
            Debug.Assert(namedValues != null, "namedValues != null");
            Debug.Assert(collectionNode != null, "CollectionNode != null");
            Debug.Assert(model != null, "model != null");

            IEdmEntityTypeReference collectionItemType = collectionNode.EntityItemType;

            IEdmEntityType collectionItemEntityType = collectionItemType.EntityDefinition();
            QueryNode keyLookupNode;

            if (TryBindToDeclaredKey(collectionNode, namedValues, model, collectionItemEntityType, out keyLookupNode))
            {
                return keyLookupNode;
            }
            else if (TryBindToDeclaredAlternateKey(collectionNode, namedValues, model, collectionItemEntityType, out keyLookupNode))
            {
                return keyLookupNode;
            }
            else
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_NotAllKeyPropertiesSpecifiedInKeyValues(collectionNode.ItemType.FullName()));
            }
        }
Example #8
0
        /// <summary>
        /// Binds key values to a key lookup on a collection.
        /// </summary>
        /// <param name="collectionNode">Already bound collection node.</param>
        /// <param name="namedValues">The named value tokens to bind.</param>
        /// <param name="model">The model to be used.</param>
        /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param>
        /// <param name="keys">Dictionary of aliases to structural property names for the key.</param>
        /// <param name="keyLookupNode">The bound key lookup.</param>
        /// <returns>Returns true if binding succeeded.</returns>
        private bool TryBindToKeys(EntityCollectionNode collectionNode, IEnumerable<NamedValue> namedValues, IEdmModel model, IEdmEntityType collectionItemEntityType, IDictionary<string, IEdmProperty> keys, out QueryNode keyLookupNode)
        {
            List<KeyPropertyValue> keyPropertyValues = new List<KeyPropertyValue>();
            HashSet<string> keyPropertyNames = new HashSet<string>(StringComparer.Ordinal);
            foreach (NamedValue namedValue in namedValues)
            {
                KeyPropertyValue keyPropertyValue;

                if (!this.TryBindKeyPropertyValue(namedValue, collectionItemEntityType, keys, out keyPropertyValue))
                {
                    keyLookupNode = null;
                    return false;
                }

                Debug.Assert(keyPropertyValue != null, "keyPropertyValue != null");
                Debug.Assert(keyPropertyValue.KeyProperty != null, "keyPropertyValue.KeyProperty != null");

                if (!keyPropertyNames.Add(keyPropertyValue.KeyProperty.Name))
                {
                    throw new ODataException(ODataErrorStrings.MetadataBinder_DuplicitKeyPropertyInKeyValues(keyPropertyValue.KeyProperty.Name));
                }

                keyPropertyValues.Add(keyPropertyValue);
            }

            if (keyPropertyValues.Count == 0)
            {
                // No key values specified, for example '/Customers()', do not include the key lookup at all
                keyLookupNode = collectionNode;
                return true;
            }
            else if (keyPropertyValues.Count != collectionItemEntityType.Key().Count())
            {
                keyLookupNode = null;
                return false;
            }
            else
            {
                keyLookupNode = new KeyLookupNode(collectionNode, new ReadOnlyCollection<KeyPropertyValue>(keyPropertyValues));
                return true;
            }
        }
Example #9
0
        /// <summary>
        /// Tries to bind key values to a key lookup on a collection.
        /// </summary>
        /// <param name="collectionNode">Already bound collection node.</param>
        /// <param name="namedValues">The named value tokens to bind.</param>
        /// <param name="model">The model to be used.</param>
        /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param>
        /// <param name="keyLookupNode">The bound key lookup.</param>
        /// <returns>Returns true if binding succeeded.</returns>
        private bool TryBindToDeclaredKey(EntityCollectionNode collectionNode, IEnumerable<NamedValue> namedValues, IEdmModel model, IEdmEntityType collectionItemEntityType, out QueryNode keyLookupNode)
        {
            Dictionary<string, IEdmProperty> keys = new Dictionary<string, IEdmProperty>(StringComparer.Ordinal);
            foreach (IEdmStructuralProperty property in collectionItemEntityType.Key())
            {
                keys[property.Name] = property;
            }

            return TryBindToKeys(collectionNode, namedValues, model, collectionItemEntityType, keys, out keyLookupNode);
        }