private void ProcessRoot(KeyLookupQueryNode keyLookup) { var keyPropertyValues = keyLookup.KeyPropertyValues.ToList(); if (keyPropertyValues.Count == 1) { var kpv = keyPropertyValues[0]; var rootEntity = kpv.KeyProperty.DeclaringType as IEdmEntityType; // Get the entity that declares the Id property if (rootEntity != null) { string prefix; if (_map.TryGetIdentifierPrefixForProperty(rootEntity.FullName(), kpv.KeyProperty.Name, out prefix)) { object keyValue = ProcessNode(kpv.KeyValue); if (keyValue != null) { _sparqlModel.SelectEntity( prefix + keyValue, keyLookup.Collection.ItemType.FullName()); } } } } }
private object ProcessKeyLookup(KeyLookupQueryNode keyLookup) { var keyPropertyValues = keyLookup.KeyPropertyValues.ToList(); if (keyPropertyValues.Count == 1) { var kpv = keyPropertyValues[0]; var rootEntity = kpv.KeyProperty.DeclaringType as IEdmEntityType; // Get the entity that declares the Id property if (rootEntity != null) { string prefix; if (_map.TryGetIdentifierPrefixForProperty(rootEntity.FullName(), kpv.KeyProperty.Name, out prefix)) { object keyValue = ProcessNode(kpv.KeyValue); if (keyValue != null) { return(new Uri(prefix + keyValue)); } } } } throw new Exception("Could not process key lookup"); }
protected virtual Expression TranslateKeyLookup(KeyLookupQueryNode keyLookupNode) { ExceptionUtils.CheckArgumentNotNull(keyLookupNode, "keyLookupNode"); ExceptionUtils.CheckArgumentNotNull(keyLookupNode.Collection, "keyLookupNode.Collection"); ExceptionUtils.CheckArgumentNotNull(keyLookupNode.Collection.ItemType, "keyLookupNode.Collection.ItemType"); ExceptionUtils.CheckArgumentNotNull(keyLookupNode.KeyPropertyValues, "keyLookupNode.KeyPropertyValues"); IEdmTypeReference itemType = keyLookupNode.Collection.ItemType; if (keyLookupNode.Collection.ItemType.TypeKind() != EdmTypeKind.Entity) { throw new ODataException(Strings.QueryExpressionTranslator_KeyLookupOnlyOnEntities(keyLookupNode.Collection.ItemType.ODataFullName(), keyLookupNode.Collection.ItemType.TypeKind())); } IEdmEntityTypeReference itemEntityType = itemType.AsEntityOrNull(); Debug.Assert(itemEntityType != null, "itemEntityType != null"); Expression collectionExpression = this.Translate(keyLookupNode.Collection); Type expectedCollectionExpressionType = typeof(IQueryable<>).MakeGenericType(itemType.GetInstanceType(this.model)); if (!expectedCollectionExpressionType.IsAssignableFrom(collectionExpression.Type)) { throw new ODataException(Strings.QueryExpressionTranslator_KeyLookupOnlyOnQueryable(collectionExpression.Type, expectedCollectionExpressionType)); } ParameterExpression parameter = Expression.Parameter(itemType.GetInstanceType(this.model), "it"); Expression body = null; // We have to walk the key properties as declared on the type to get the declared order (rather than the order in the query) // So we need to cache the key properties in a list so that we can look them up. This is necessary to avoid enumerating the IEnumerable // specified on the Key lookup node multiple times (since we don't know how costly it is and if it's actually possible). List<KeyPropertyValue> keyPropertyValuesCache = new List<KeyPropertyValue>(keyLookupNode.KeyPropertyValues); foreach (IEdmStructuralProperty keyProperty in itemEntityType.Key()) { // Find the value for the key property and verify that it's specified exactly once. KeyPropertyValue keyPropertyValue = null; foreach (KeyPropertyValue candidateKeyPropertyValue in keyPropertyValuesCache.Where(kpv => kpv.KeyProperty == keyProperty)) { if (keyPropertyValue != null) { throw new ODataException(Strings.QueryExpressionTranslator_KeyLookupWithoutKeyProperty(keyProperty.Name, itemType.ODataFullName())); } keyPropertyValue = candidateKeyPropertyValue; } if (keyPropertyValue == null) { throw new ODataException(Strings.QueryExpressionTranslator_KeyLookupWithoutKeyProperty(keyProperty.Name, itemType.ODataFullName())); } // NOTE: using Any() instead of Contains() since Contains() does not exist on all platforms if (keyPropertyValue.KeyProperty == null || !itemEntityType.Key().Any(k => k == keyPropertyValue.KeyProperty)) { throw new ODataException(Strings.QueryExpressionTranslator_KeyPropertyValueWithoutProperty); } if (keyPropertyValue.KeyValue == null || keyPropertyValue.KeyValue.TypeReference == null || !keyPropertyValue.KeyValue.TypeReference.IsEquivalentTo(keyPropertyValue.KeyProperty.Type)) { throw new ODataException(Strings.QueryExpressionTranslator_KeyPropertyValueWithWrongValue(keyPropertyValue.KeyProperty.Name)); } Expression keyPropertyAccess = this.CreatePropertyAccessExpression(parameter, itemEntityType, keyPropertyValue.KeyProperty); Expression keyValueExpression = this.Translate(keyPropertyValue.KeyValue); #if DEBUG Debug.Assert( TypeUtils.AreTypesEquivalent(keyPropertyAccess.Type, keyValueExpression.Type), "The types of the expression should have been checked against the metadata types which are equal."); #endif Expression keyPredicate = Expression.Equal( keyPropertyAccess, keyValueExpression); if (body == null) { body = keyPredicate; } else { body = Expression.AndAlso(body, keyPredicate); } } if (body == null) { throw new ODataException(Strings.QueryExpressionTranslator_KeyLookupWithNoKeyValues); } return Expression.Call( typeof(Queryable), WhereMethodName, new Type[] { itemType.GetInstanceType(this.model) }, collectionExpression, Expression.Quote(Expression.Lambda(body, parameter))); }
private object ProcessKeyLookup(KeyLookupQueryNode keyLookup) { var keyPropertyValues = keyLookup.KeyPropertyValues.ToList(); if (keyPropertyValues.Count == 1) { var kpv = keyPropertyValues[0]; var rootEntity = kpv.KeyProperty.DeclaringType as IEdmEntityType; // Get the entity that declares the Id property if (rootEntity != null) { string prefix; if (_map.TryGetIdentifierPrefixForProperty(rootEntity.FullName(), kpv.KeyProperty.Name, out prefix)) { object keyValue = ProcessNode(kpv.KeyValue); if (keyValue != null) { return new Uri(prefix + keyValue); } } } } throw new Exception("Could not process key lookup"); }