コード例 #1
0
        public void CreateNamedPropertyExpression_NonDerivedProperty_ReturnsMemberAccessExpression(HandleNullPropagationOption options)
        {
            SelectExpandBinder binder = GetBinder <Customer>(_model, options);

            Expression             customer            = Expression.Constant(new Customer());
            IEdmStructuralProperty homeAddressProperty = _customer.StructuralProperties().Single(c => c.Name == "HomeLocation");

            ODataSelectPath selectPath     = new ODataSelectPath(new PropertySegment(homeAddressProperty));
            PathSelectItem  pathSelectItem = new PathSelectItem(selectPath);

            NamedPropertyExpression namedProperty = binder.CreateNamedPropertyExpression(customer, _customer, pathSelectItem);

            Assert.NotNull(namedProperty);
            Assert.Equal("\"HomeLocation\"", namedProperty.Name.ToString());

            if (options != HandleNullPropagationOption.True)
            {
                Assert.Equal("value(NS.Customer).HomeLocation", namedProperty.Value.ToString());
            }
            else
            {
                Assert.Equal("IIF((value(NS.Customer) == null)," +
                             " null," +
                             " value(NS.Customer).HomeLocation)", namedProperty.Value.ToString());
            }
        }
コード例 #2
0
        internal static SelectedPropertiesNode IncludeEntireSubtree(this SelectedPropertiesNode node, IEdmEntityType entityType)
        {
            var expected = entityType.StructuralProperties().Where(p => p.Type.IsStream());
            var edmStructuralProperties = node.GetSelectedStreamProperties(entityType).Values;

            Assert.Equal(expected.Count(), edmStructuralProperties.Count);
            foreach (var prop in edmStructuralProperties)
            {
                Assert.Contains(prop, expected);
            }

            var navExpected      = entityType.NavigationProperties();
            var edmNavProperties = node.GetSelectedNavigationProperties(entityType);

            Assert.Equal(navExpected.Count(), edmNavProperties.Count());
            foreach (var prop in edmNavProperties)
            {
                Assert.Contains(prop, navExpected);
            }

            foreach (var navigation in entityType.NavigationProperties())
            {
                node.GetSelectedPropertiesForNavigationProperty(entityType, navigation.Name).HaveEntireSubtree();
            }

            return(node);
        }
コード例 #3
0
        /// <summary>
        /// Retrieves the paths for a media entity stream.
        /// </summary>
        /// <param name="entityType">The entity type.</param>
        /// <param name="currentPath">The current OData path.</param>
        private void RetrieveMediaEntityStreamPaths(IEdmEntityType entityType, ODataPath currentPath)
        {
            Debug.Assert(entityType != null);
            Debug.Assert(currentPath != null);

            bool createValuePath = true;

            foreach (IEdmStructuralProperty sp in entityType.StructuralProperties())
            {
                if (sp.Type.AsPrimitive().IsStream())
                {
                    currentPath.Push(new ODataStreamPropertySegment(sp.Name));
                    AppendPath(currentPath.Clone());
                    currentPath.Pop();
                }

                if (sp.Name.Equals("content", StringComparison.OrdinalIgnoreCase))
                {
                    createValuePath = false;
                }
            }

            /* Create a /$value path only if entity has stream and
             * does not contain a structural property named Content
             */
            if (createValuePath && entityType.HasStream)
            {
                currentPath.Push(new ODataStreamContentSegment());
                AppendPath(currentPath.Clone());
                currentPath.Pop();
            }
        }
コード例 #4
0
        public EdmDeltaModel(IEdmModel source, IEdmEntityType entityType, IEnumerable <string> propertyNames)
        {
            _source     = source;
            _entityType = new EdmEntityType(entityType.Namespace, entityType.Name);

            foreach (var property in entityType.StructuralProperties())
            {
                if (propertyNames.Contains(property.Name))
                {
                    _entityType.AddStructuralProperty(property.Name, property.Type, property.DefaultValueString, property.ConcurrencyMode);
                }
            }

            foreach (var property in entityType.NavigationProperties())
            {
                if (propertyNames.Contains(property.Name))
                {
                    var navInfo = new EdmNavigationPropertyInfo()
                    {
                        ContainsTarget      = property.ContainsTarget,
                        DependentProperties = property.DependentProperties(),
                        Name     = property.Name,
                        OnDelete = property.OnDelete,
                        Target   = property.Partner != null
                            ? property.Partner.DeclaringEntityType()
                            : property.Type.TypeKind() == EdmTypeKind.Collection
                            ? (property.Type.Definition as IEdmCollectionType).ElementType.Definition as IEdmEntityType
                            : null,
                        TargetMultiplicity = property.TargetMultiplicity(),
                    };
                    _entityType.AddUnidirectionalNavigation(navInfo);
                }
            }
        }
コード例 #5
0
        public void CreateNamedPropertyExpression_WithDerivedProperty_ReturnsMemberAccessExpression(HandleNullPropagationOption options)
        {
            SelectExpandBinder binder = GetBinder <Customer>(_model, options);

            //Expression customer = Expression.Parameter(typeof(Customer)); output will be different.
            Expression             customer           = Expression.Constant(new Customer());
            IEdmStructuralProperty vipAddressProperty = _vipCustomer.StructuralProperties().Single(c => c.Name == "VipAddress");

            ODataSelectPath selectPath = new ODataSelectPath(new TypeSegment(_vipCustomer, _customer, null),
                                                             new PropertySegment(vipAddressProperty));
            PathSelectItem pathSelectItem = new PathSelectItem(selectPath);

            NamedPropertyExpression namedProperty = binder.CreateNamedPropertyExpression(customer, _customer, pathSelectItem);

            Assert.NotNull(namedProperty);
            Assert.Equal("\"VipAddress\"", namedProperty.Name.ToString());

            if (options != HandleNullPropagationOption.True)
            {
                Assert.Equal("(value(NS.Customer) As VipCustomer).VipAddress", namedProperty.Value.ToString());
            }
            else
            {
                Assert.Equal("IIF(((value(NS.Customer) As VipCustomer) == null)," +
                             " null," +
                             " (value(NS.Customer) As VipCustomer).VipAddress)", namedProperty.Value.ToString());
            }
        }
コード例 #6
0
        public void EntityType_reference_extensions()
        {
            IEdmModel      edmModel          = this.GetEdmModel();
            IEdmEntityType derivedEntityType = edmModel.SchemaElements.OfType <IEdmEntityType>().First(c => c.BaseType != null);
            IEdmEntityType baseEntityType    = derivedEntityType.BaseEntityType();

            Assert.IsNotNull(baseEntityType, "Base entity type should not be null!");

            IEdmEntityTypeReference derivedEntityTypeRef = (IEdmEntityTypeReference)derivedEntityType.ToTypeReference();

            Assert.AreEqual(baseEntityType, derivedEntityTypeRef.BaseEntityType(), "EntityTypeReference.BaseEntityType()");
            Assert.AreEqual(baseEntityType, derivedEntityTypeRef.BaseType(), "EntityTypeReference.BaseType()");

            Assert.AreEqual(derivedEntityType.IsAbstract, derivedEntityTypeRef.IsAbstract(), "StructuralTypeReference.IsAbstract()");
            Assert.AreEqual(derivedEntityType.IsOpen, derivedEntityTypeRef.IsOpen(), "StructuralTypeReference.IsOpen()");

            Assert.AreEqual(derivedEntityType.DeclaredStructuralProperties().Count(), derivedEntityTypeRef.DeclaredStructuralProperties().Count(), "StructuralTypeReference.DeclaredStructuralProperties()");
            Assert.AreEqual(derivedEntityType.StructuralProperties().Count(), derivedEntityTypeRef.StructuralProperties().Count(), "StructuralTypeReference.StructuralProperties()");

            Assert.AreEqual(derivedEntityType.DeclaredNavigationProperties().Count(), derivedEntityTypeRef.DeclaredNavigationProperties().Count(), "EntityTypeReference.DeclaredNavigationProperties()");
            Assert.AreEqual(derivedEntityType.NavigationProperties().Count(), derivedEntityTypeRef.NavigationProperties().Count(), "EntityTypeReference.NavigationProperties()");

            IEdmNavigationProperty result = derivedEntityTypeRef.FindNavigationProperty("_Not_Exist_");

            Assert.IsNull(result, "Should not find Navigation Property {0}", "_Not_Exist_");

            var navigation = derivedEntityType.NavigationProperties().First();

            result = derivedEntityTypeRef.FindNavigationProperty(navigation.Name);
            Assert.AreEqual(navigation, result, "FindNavigationProperty({0})", navigation.Name);
        }
            static OrderBySetting FindProperties(IEdmEntityType entity)
            {
                var propertyNames = entity.Key().Any() switch
                {
                    true => entity.Key().Select(k => k.Name),
                    false => entity.StructuralProperties()
                    .Where(p => p.Type.IsPrimitive() && !p.Type.IsStream())
                    .Select(p => p.Name)
                    .OrderBy(n => n)
                    .Take(1)
                };
                var orderBySettings = new OrderBySetting();

                propertyNames.Aggregate(orderBySettings, (settings, name) =>
                {
                    if (settings.Name is null)
                    {
                        settings.Name = name;
                        return(settings);
                    }
                    settings.ThenBy = new() { Name = name };
                    return(settings.ThenBy);
                });
                return(orderBySettings.Name is null ? null : orderBySettings);
            }
        }
    }
コード例 #8
0
        /// <summary>
        /// Create entity class from EDMX entity definition.
        /// </summary>
        /// <param name="entityType">entity type from CSDL</param>
        /// <returns>class defination string</returns>
        /// <remarks>
        /// References
        /// - http://roslynquoter.azurewebsites.net/
        /// - https://gist.github.com/cmendible/9b8c7d7598f1ab0bc7ab5d24b2622622
        /// - https://joshvarty.com/2015/09/18/learn-roslyn-now-part-13-keeping-track-of-syntax-nodes-with-syntax-annotations/
        /// </remarks>
        public static CompilationUnitSyntax From(IEdmEntityType entityType)
        {
            var name = entityType.Name;

            // [Table("Foo")]
            // public class Foo { }
            var @class = ClassDeclaration(name)
                         .AddModifiers(PublicModifier())
                         .AddAttribute(Attribute("Table", name));

            foreach (var structuralProp in entityType.StructuralProperties())
            {
                @class = @class.AddMembers(GetPropertyDeclarationSyntax(structuralProp));
            }
            foreach (var navigationProp in entityType.NavigationProperties())
            {
                @class = @class.AddMembers(GetPropertyDeclarationSyntax(navigationProp));
            }

            // namespace SampleModel { }
            var @namespace = NamespaceDeclaration(entityType.Namespace)
                             .AddMembers(@class);

            // using System;
            var root = CompilationUnit()
                       .AddUsings("System",
                                  "System.Collections.Generic",
                                  "System.ComponentModel.DataAnnotations",
                                  "System.ComponentModel.DataAnnotations.Schema")
                       .AddMembers(@namespace);

            return(root);
        }
コード例 #9
0
        /// <summary>
        /// Converts an item from the data store into an ODataEntry.
        /// </summary>
        /// <param name="element">The item to convert.</param>
        /// <param name="entitySet">The entity set that the item belongs to.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <returns>The converted ODataEntry.</returns>
        public static ODataEntry ConvertToODataEntry(object element, IEdmEntitySet entitySet, ODataVersion targetVersion)
        {
            IEdmEntityType entityType = entitySet.EntityType();

            Uri entryUri = BuildEntryUri(element, entitySet, targetVersion);

            var entry = new ODataEntry
            {
                // writes out the edit link including the service base uri  , e.g.: http://<serviceBase>/Customers('ALFKI')
                EditLink = entryUri,

                // writes out the self link including the service base uri  , e.g.: http://<serviceBase>/Customers('ALFKI')
                ReadLink = entryUri,

                // we use the EditLink as the Id for this entity to maintain convention,
                Id = entryUri,

                // writes out the <category term='Customer'/> element
                TypeName = element.GetType().Namespace + "." + entityType.Name,

                Properties = entityType.StructuralProperties().Select(p => ConvertToODataProperty(element, p.Name)),
            };

            return(entry);
        }
コード例 #10
0
        private static string GenerateDefaultOrderBy(ODataQueryContext context)
        {
            Contract.Assert(context != null && context.EntitySet != null);

            IEdmEntityType entityType = context.EntitySet.ElementType;

            // choose the keys alphabetically. This would return a stable sort.
            string sortOrder = String.Join(",", entityType
                                           .Key()
                                           .OrderBy(property => property.Name)
                                           .Select(property => property.Name));

            if (String.IsNullOrEmpty(sortOrder))
            {
                // If there are no keys, choose the primitive properties alphabetically. This
                // might not result in a stable sort especially if there are duplicates and is only
                // a best effort solution.
                sortOrder = String.Join(",", entityType
                                        .StructuralProperties()
                                        .Where(property => property.Type.IsPrimitive())
                                        .OrderBy(property => property.Name)
                                        .Select(property => property.Name));
            }

            return(sortOrder);
        }
コード例 #11
0
        public void Index([FromBody] ODataUntypedActionParameters parameters)
        {
            IEdmModel model = Request.ODataProperties().Model;
            IEdmEntityTypeReference docTypeRef = model.GetDocTypeRef();
            IEdmEntityType          docType    = docTypeRef.EntityDefinition();

            IEdmEntityObject CopyDocument(IEdmComplexObject source)
            {
                var target = new EdmEntityObject(docTypeRef);

                foreach (string propertyName in docType.StructuralProperties().Select(p => p.Name))
                {
                    if (source.TryGetPropertyValue(propertyName, out object propertyValue))
                    {
                        target.TrySetPropertyValue(propertyName, propertyValue);
                    }
                }

                return(target);
            }

            var documentsObjects = (EdmComplexObjectCollection)parameters["value"];
            IEnumerable <IEdmEntityObject> documents = documentsObjects.Select(CopyDocument);

            Documents.AddRange(documents);
        }
コード例 #12
0
        public EdmDeltaModel(IEdmModel source, IEdmEntityType entityType, IEnumerable<string> propertyNames)
        {
            _source = source;
            _entityType = new EdmEntityType(entityType.Namespace, entityType.Name);

            foreach (var property in entityType.StructuralProperties())
            {
                if (propertyNames.Contains(property.Name))
                    _entityType.AddStructuralProperty(property.Name, property.Type, property.DefaultValueString, property.ConcurrencyMode);
            }

            foreach (var property in entityType.NavigationProperties())
            {
                if (propertyNames.Contains(property.Name))
                {
                    var navInfo = new EdmNavigationPropertyInfo()
                    {
                        ContainsTarget = property.ContainsTarget,
                        DependentProperties = property.DependentProperties(),
                        PrincipalProperties = property.PrincipalProperties(),
                        Name = property.Name,
                        OnDelete = property.OnDelete,
                        Target = property.Partner != null 
                            ? property.Partner.DeclaringEntityType()
                            : property.Type.TypeKind() == EdmTypeKind.Collection
                            ? (property.Type.Definition as IEdmCollectionType).ElementType.Definition as IEdmEntityType
                            : property.Type.TypeKind() == EdmTypeKind.Entity
                            ? property.Type.Definition as IEdmEntityType
                            : null,
                        TargetMultiplicity = property.TargetMultiplicity(),
                    };
                    _entityType.AddUnidirectionalNavigation(navInfo);
                }
            }
        }
コード例 #13
0
        internal static string GetJsonPayload(IEdmEntityType entityType, object value)
        {
            Type          valueType = value.GetType();
            StringBuilder sb        = new StringBuilder();

            sb.Append("{");
            sb.Append(Environment.NewLine);
            sb.Append("\t");
            sb.Append("@odata.type: \"" + entityType.FullName() + "\",");
            var properties = entityType.StructuralProperties().ToList();

            for (int i = 0; i < properties.Count; i++)
            {
                sb.Append("\t");
                IEdmProperty property = properties[i];
                // Type propertyType = ((PrimitiveType)property.TypeUsage.EdmType).ClrEquivalentType;
                PropertyInfo propertyInfo = valueType.GetProperty(property.Name);
                Type         propertyType = propertyInfo.PropertyType;
                propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;
                object propertyValue = propertyInfo.GetValue(value, null);
                sb.Append(String.Format("{0}:{1}", properties[i].Name, PrimitiveToString(propertyValue, propertyType)));
                if (i != properties.Count - 1)
                {
                    sb.Append(",");
                }
                sb.Append(Environment.NewLine);
            }
            sb.Append("}");

            return(sb.ToString());
        }
コード例 #14
0
        /// <summary>
        /// Create $orderby parameter for the <see cref="IEdmEntitySet"/>.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="target">The Edm annotation target.</param>
        /// <returns>The created <see cref="OpenApiParameter"/> or null.</returns>
        public static OpenApiParameter CreateOrderBy(this ODataContext context, IEdmVocabularyAnnotatable target, IEdmEntityType entityType)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(target, nameof(target));
            Utils.CheckArgumentNull(entityType, nameof(entityType));

            SortRestrictions sort = context.Model.GetSortRestrictions(target);

            if (sort != null && !sort.IsSortable)
            {
                return(null);
            }

            IList <IOpenApiAny> orderByItems = new List <IOpenApiAny>();

            foreach (var property in entityType.StructuralProperties())
            {
                if (sort != null && sort.IsNonSortableProperty(property.Name))
                {
                    continue;
                }

                bool isAscOnly = sort != null?sort.IsAscendingOnlyProperty(property.Name) : false;

                bool isDescOnly = sort != null?sort.IsDescendingOnlyProperty(property.Name) : false;

                if (isAscOnly || isDescOnly)
                {
                    if (isAscOnly)
                    {
                        orderByItems.Add(new OpenApiString(property.Name));
                    }
                    else
                    {
                        orderByItems.Add(new OpenApiString(property.Name + " desc"));
                    }
                }
                else
                {
                    orderByItems.Add(new OpenApiString(property.Name));
                    orderByItems.Add(new OpenApiString(property.Name + " desc"));
                }
            }

            return(new OpenApiParameter
            {
                Name = "$orderby",
                In = ParameterLocation.Query,
                Description = "Order items by property values",
                Schema = new OpenApiSchema
                {
                    // Remove array in favor of single instance for PowerApps
                    Type = "string",
                    Enum = orderByItems
                },
                Style = ParameterStyle.Simple
            });
        }
コード例 #15
0
        public static IList <string> CreateSelectItems(this IEdmEntityType entityType)
        {
            IList <string> selectItems = new List <string>();

            foreach (var property in entityType.StructuralProperties())
            {
                selectItems.Add(property.Name);
            }

            return(selectItems);
        }
コード例 #16
0
        /// <summary>
        /// Retrieves the paths for properties of type complex type from entities
        /// </summary>
        /// <param name="entityType">The entity type.</param>
        /// <param name="currentPath">The current path.</param>
        /// <param name="convertSettings">The settings for the current conversion.</param>
        private void RetrieveComplexPropertyPaths(IEdmEntityType entityType, ODataPath currentPath, OpenApiConvertSettings convertSettings)
        {
            Debug.Assert(entityType != null);
            Debug.Assert(currentPath != null);
            Debug.Assert(convertSettings != null);

            if (!convertSettings.EnableNavigationPropertyPath)
            {
                return;
            }

            foreach (IEdmStructuralProperty sp in entityType.StructuralProperties()
                     .Where(x => x.Type.IsComplex() ||
                            x.Type.IsCollection() && x.Type.Definition.AsElementType() is IEdmComplexType))
            {
                if (!ShouldCreateComplexPropertyPaths(sp, convertSettings))
                {
                    continue;
                }

                currentPath.Push(new ODataComplexPropertySegment(sp));
                AppendPath(currentPath.Clone());


                if (sp.Type.IsCollection())
                {
                    CreateTypeCastPaths(currentPath, convertSettings, sp.Type.Definition.AsElementType() as IEdmComplexType, sp, true);
                    var count = _model.GetRecord <CountRestrictionsType>(sp, CapabilitiesConstants.CountRestrictions);
                    if (count?.IsCountable ?? true)
                    {
                        CreateCountPath(currentPath, convertSettings);
                    }
                }
                else
                {
                    var complexTypeReference = sp.Type.AsComplex();
                    var definition           = complexTypeReference.ComplexDefinition();

                    CreateTypeCastPaths(currentPath, convertSettings, definition, sp, false);
                    foreach (IEdmNavigationProperty np in complexTypeReference
                             .DeclaredNavigationProperties()
                             .Union(definition
                                    .FindAllBaseTypes()
                                    .SelectMany(x => x.DeclaredNavigationProperties()))
                             .Distinct()
                             .Where(CanFilter))
                    {
                        var count = _model.GetRecord <CountRestrictionsType>(np, CapabilitiesConstants.CountRestrictions);
                        RetrieveNavigationPropertyPaths(np, count, currentPath, convertSettings);
                    }
                }
                currentPath.Pop();
            }
        }
コード例 #17
0
        internal EntityTypeInfo(IEdmModel edmModel, IEdmEntityType edmEntityType, ITypeResolver typeResolver)
        {
            Contract.Assert(edmModel != null);
            Contract.Assert(edmEntityType != null);
            Contract.Assert(typeResolver != null);

            _edmEntityType = edmEntityType;
            string edmTypeName = edmEntityType.FullName();
            _type = typeResolver.ResolveTypeFromName(edmTypeName);

            // Initialize DontSerializeProperties
            _dontSerializeProperties = _type.GetProperties().Where(p => p.GetCustomAttributes(typeof(IgnoreDataMemberAttribute), true).Length > 0).Select(p => p.Name).ToArray();

            //edmEntityType.DeclaredKey;
            //edmEntityType.BaseEntityType();
            var structuralProperties = new List<PropertyInfo>();
            foreach (var edmStructuralProperty in edmEntityType.StructuralProperties())
            {
                if (! _dontSerializeProperties.Contains(edmStructuralProperty.Name))
                {
                    structuralProperties.Add(_type.GetProperty(edmStructuralProperty.Name));
                }
            }

            // EF can pick up private properties (eg: those marked as navigational).  We omit them on spec.
            _structuralProperties = structuralProperties.Where(p => p != null).ToArray();

            var navigationProperties = new List<PropertyInfo>();
            var linkProperties = new List<PropertyInfo>();
            foreach (var edmNavigationProperty in edmEntityType.NavigationProperties())
            {
                if (! _dontSerializeProperties.Contains(edmNavigationProperty.Name))
                {
                    if (edmNavigationProperty.Type.IsCollection())
                    {
                        linkProperties.Add(_type.GetProperty(edmNavigationProperty.Name));
                    }
                    else
                    {
                        navigationProperties.Add(_type.GetProperty(edmNavigationProperty.Name));
                    }
                }
            }
            _navigationProperties = navigationProperties.Where(p => p != null).ToArray();
            _collectionProperties = linkProperties.Where(p => p != null).ToArray();

            // Reflect for ValidationAttributes on all properties
            var validationInfo = new List<PropertyValidationInfo>();
            InitValidationInfo(validationInfo, _structuralProperties, PropertyCategory.Structural);
            InitValidationInfo(validationInfo, _navigationProperties, PropertyCategory.Navigation);
            InitValidationInfo(validationInfo, _collectionProperties, PropertyCategory.Collection);
            _propertyValidationInfo = validationInfo.ToArray();
        }
コード例 #18
0
        // new CollectionWrapper<ElementType> { Instance = source.Select((ElementType element) => new Wrapper { }) }
        private Expression ProjectCollection(Expression source, Type elementType, SelectExpandClause selectExpandClause, IEdmEntityType entityType, IEdmEntitySet entitySet)
        {
            ParameterExpression element = Expression.Parameter(elementType);

            // expression
            //      new Wrapper { }
            Expression projection = ProjectElement(element, selectExpandClause, entityType, entitySet);

            // expression
            //      (ElementType element) => new Wrapper { }
            LambdaExpression selector = Expression.Lambda(projection, element);

            if (_settings.PageSize != null && _settings.PageSize.HasValue)
            {
                // nested paging. Need to apply order by first, and take one more than page size as we need to know
                // whether the collection was truncated or not while generating next page links.
                IEnumerable <IEdmStructuralProperty> properties =
                    entityType.Key().Any()
                        ? entityType.Key()
                        : entityType
                    .StructuralProperties()
                    .Where(property => property.Type.IsPrimitive()).OrderBy(property => property.Name);
                bool alreadyOrdered = false;
                foreach (var prop in properties)
                {
                    source = ExpressionHelpers.OrderByPropertyExpression(source, prop.Name, elementType, alreadyOrdered);
                    if (!alreadyOrdered)
                    {
                        alreadyOrdered = true;
                    }
                }

                source = ExpressionHelpers.Take(source, _settings.PageSize.Value + 1, elementType, _settings.EnableConstantParameterization);
            }

            // expression
            //      source.Select((ElementType element) => new Wrapper { })
            Expression selectedExpresion = Expression.Call(GetSelectMethod(elementType, projection.Type), source, selector);

            if (_settings.HandleNullPropagation == HandleNullPropagationOption.True)
            {
                // source == null ? null : projectedCollection
                return(Expression.Condition(
                           test: Expression.Equal(source, Expression.Constant(null)),
                           ifTrue: Expression.Constant(null, selectedExpresion.Type),
                           ifFalse: selectedExpresion));
            }
            else
            {
                return(selectedExpresion);
            }
        }
コード例 #19
0
        public override IEnumerable <DynamicPropertyInfo> GetStructuralProperties(String tableName)
        {
            IEdmEntityType edmEntityType = OeEdmClrHelper.GetEntitySet(_edmModel, tableName).EntityType();
            Type           clrType       = _edmModel.GetClrType(edmEntityType);

            foreach (IEdmStructuralProperty structuralProperty in edmEntityType.StructuralProperties())
            {
                PropertyInfo property = clrType.GetProperty(structuralProperty.Name);
                DatabaseGeneratedAttribute attribute = property.GetCustomAttribute <DatabaseGeneratedAttribute>();
                DatabaseGeneratedOption    databaseGeneratedOption = attribute == null ?
                                                                     DatabaseGeneratedOption.None : databaseGeneratedOption = attribute.DatabaseGeneratedOption;
                yield return(new DynamicPropertyInfo(structuralProperty.Name, property.PropertyType, databaseGeneratedOption));
            }
        }
コード例 #20
0
        public static IList <string> CreateOrderbyItems(this IEdmEntitySet entitySet)
        {
            IList <string> orderByItems = new List <string>();

            IEdmEntityType entityType = entitySet.EntityType();

            foreach (var property in entityType.StructuralProperties())
            {
                orderByItems.Add(property.Name);
                orderByItems.Add(property.Name + " desc");
            }

            return(orderByItems);
        }
コード例 #21
0
        // Returns a sorted list of all properties that may legally appear
        // in an OrderBy.  If the entity type has keys, all are returned.
        // Otherwise, when no keys are present, all primitive properties are returned.
        private static IEnumerable <IEdmStructuralProperty> GetAvailableOrderByProperties(ODataQueryContext context)
        {
            Contract.Assert(context != null && context.EntitySet != null);

            IEdmEntityType entityType = context.EntitySet.ElementType;
            IEnumerable <IEdmStructuralProperty> properties =
                entityType.Key().Any()
                    ? entityType.Key()
                    : entityType
                .StructuralProperties()
                .Where(property => property.Type.IsPrimitive());

            // Sort properties alphabetically for stable sort
            return(properties.OrderBy(property => property.Name));
        }
コード例 #22
0
        private void CompareEntityType(IEdmEntityType expectedEntityType, IEdmEntityType actualEntityType)
        {
            this.SatisfiesEquals(expectedEntityType.FullName(), actualEntityType.FullName(), "EntityType name does not match.");
            this.SatisfiesEquals(expectedEntityType.IsAbstract, actualEntityType.IsAbstract, "IsAbstract does not match for EntityType '{0}'.", expectedEntityType.FullName());

            string expectedBaseTypeName = expectedEntityType.BaseType != null ? ((IEdmSchemaElement)expectedEntityType.BaseType).FullName() : null;
            string actualBaseTypeName   = actualEntityType.BaseType != null ? ((IEdmSchemaElement)actualEntityType.BaseType).FullName() : null;

            this.SatisfiesEquals(expectedBaseTypeName, actualBaseTypeName, "BaseType does not match for EntityType '{0}'.", expectedEntityType.FullName());
            this.CompareProperties(expectedEntityType.StructuralProperties().Cast <IEdmProperty>(), actualEntityType.StructuralProperties().Cast <IEdmProperty>());
            this.CompareProperties(expectedEntityType.Key().OfType <IEdmProperty>(), actualEntityType.Key().OfType <IEdmProperty>());
            this.CompareNavigationProperty(expectedEntityType.Properties().OfType <IEdmNavigationProperty>(), actualEntityType.Properties().OfType <IEdmNavigationProperty>());

            this.CompareTermAnnotations(expectedEntityType, actualEntityType);
        }
コード例 #23
0
        /// <summary>
        /// Create $select parameter for the <see cref="IEdmVocabularyAnnotatable"/>.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="target">The Edm target.</param>
        /// <param name="entityType">The Edm entity type.</param>
        /// <returns>The created <see cref="OpenApiParameter"/> or null.</returns>
        public static OpenApiParameter CreateSelect(this ODataContext context, IEdmVocabularyAnnotatable target, IEdmEntityType entityType)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(target, nameof(target));
            Utils.CheckArgumentNull(entityType, nameof(entityType));

            NavigationRestrictionsType navigation = context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions);

            if (navigation != null && !navigation.IsNavigable)
            {
                return(null);
            }

            IList <IOpenApiAny> selectItems = new List <IOpenApiAny>();

            foreach (var property in entityType.StructuralProperties())
            {
                selectItems.Add(new OpenApiString(property.Name));
            }

            foreach (var property in entityType.NavigationProperties())
            {
                if (navigation != null && navigation.IsRestrictedProperty(property.Name))
                {
                    continue;
                }

                selectItems.Add(new OpenApiString(property.Name));
            }

            return(new OpenApiParameter
            {
                Name = "$select",
                In = ParameterLocation.Query,
                Description = "Select properties to be returned",
                Schema = new OpenApiSchema
                {
                    Type = "array",
                    UniqueItems = true,
                    Items = new OpenApiSchema
                    {
                        Type = "string",
                        Enum = selectItems
                    }
                },
                Style = ParameterStyle.Form
            });
        }
コード例 #24
0
ファイル: SelectExpandNode.cs プロジェクト: joshcomley/WebApi
        /// <summary>
        /// Creates a new instance of the <see cref="SelectExpandNode"/> class describing the set of structural properties,
        /// navigation properties, and actions to select and expand for the given <paramref name="selectExpandClause"/>.
        /// </summary>
        /// <param name="selectExpandClause">The parsed $select and $expand query options.</param>
        /// <param name="entityType">The entity type of the entry that would be written.</param>
        /// <param name="model">The <see cref="IEdmModel"/> that contains the given entity type.</param>
        public SelectExpandNode(SelectExpandClause selectExpandClause, IEdmEntityType entityType, IEdmModel model)
            : this()
        {
            if (entityType == null)
            {
                throw Error.ArgumentNull("entityType");
            }
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            HashSet<IEdmStructuralProperty> allStructuralProperties = new HashSet<IEdmStructuralProperty>(entityType.StructuralProperties());
            HashSet<IEdmNavigationProperty> allNavigationProperties = new HashSet<IEdmNavigationProperty>(entityType.NavigationProperties());
            HashSet<IEdmAction> allActions = new HashSet<IEdmAction>(model.GetAvailableActions(entityType));
            HashSet<IEdmFunction> allFunctions = new HashSet<IEdmFunction>(model.GetAvailableFunctions(entityType));

            if (selectExpandClause == null)
            {
                SelectedStructuralProperties = allStructuralProperties;
                SelectedNavigationProperties = allNavigationProperties;
                SelectedActions = allActions;
                SelectedFunctions = allFunctions;
                SelectAllDynamicProperties = true;
            }
            else
            {
                if (selectExpandClause.AllSelected)
                {
                    SelectedStructuralProperties = allStructuralProperties;
                    SelectedNavigationProperties = allNavigationProperties;
                    SelectedActions = allActions;
                    SelectedFunctions = allFunctions;
                    SelectAllDynamicProperties = true;
                }
                else
                {
                    BuildSelections(selectExpandClause, allStructuralProperties, allNavigationProperties, allActions, allFunctions);
                    SelectAllDynamicProperties = false;
                }

                BuildExpansions(selectExpandClause, allNavigationProperties);

                // remove expanded navigation properties from the selected navigation properties.
                SelectedNavigationProperties.ExceptWith(ExpandedNavigationProperties.Keys);
            }
        }
コード例 #25
0
        // <summary>
        /// Create $select parameter for the <see cref="IEdmNavigationSource"/>.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="navigationSource">The Edm navigation source.</param>
        /// <returns>The created <see cref="OpenApiParameter"/> or null.</returns>
        public static OpenApiParameter CreateSelect(this ODataContext context, IEdmVocabularyAnnotatable target, IEdmEntityType entityType)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(target, nameof(target));
            Utils.CheckArgumentNull(entityType, nameof(entityType));

            NavigationRestrictions navigation = context.Model.GetNavigationRestrictions(target);

            if (navigation != null && !navigation.IsNavigable)
            {
                return(null);
            }

            IList <IOpenApiAny> selectItems = new List <IOpenApiAny>();

            foreach (var property in entityType.StructuralProperties())
            {
                selectItems.Add(new OpenApiString(property.Name));
            }

            foreach (var property in entityType.NavigationProperties())
            {
                if (navigation != null && navigation.IsRestrictedProperty(property.Name))
                {
                    continue;
                }

                selectItems.Add(new OpenApiString(property.Name));
            }

            return(new OpenApiParameter
            {
                Name = "$select",
                In = ParameterLocation.Query,
                Description = "Select properties to be returned",
                Schema = new OpenApiSchema
                {
                    // Remove array in favor of single instance for PowerApps
                    Type = "string",
                    Enum = selectItems
                },
                Style = ParameterStyle.Simple
            });
        }
コード例 #26
0
 private static IEnumerable <string> PopuldateFieldList(IEdmEntityType entityType)
 {
     foreach (var property in entityType.StructuralProperties())
     {
         yield return(property.Name);
     }
     foreach (var property in entityType.NavigationProperties())
     {
         var typeKind = property.Type.TypeKind();
         if (typeKind == EdmTypeKind.Entity)
         {
             var navigationPropertyType = property.Type.AsEntity();
             foreach (var childProperty in navigationPropertyType.StructuralProperties())
             {
                 string propertyName = string.Format("{0}.{1}", property.Name, childProperty.Name);
                 yield return(propertyName);
             }
         }
     }
 }
コード例 #27
0
        /// <summary>
        /// Gets the selected stream properties for the current node.
        /// </summary>
        /// <param name="entityType">The current entity type.</param>
        /// <returns>The selected stream properties.</returns>
        internal IDictionary <string, IEdmStructuralProperty> GetSelectedStreamProperties(IEdmEntityType entityType)
        {
            DebugUtils.CheckNoExternalCallers();

            if (this.selectionType == SelectionType.Empty)
            {
                return(EmptyStreamProperties);
            }

            // We cannot determine the selected stream properties without the user model. This means we won't be computing the missing stream properties.
            // For reading we will report what's on the wire and for writing we just write what the user explicitely told us to write.
            if (entityType == null)
            {
                return(EmptyStreamProperties);
            }

            if (this.selectionType == SelectionType.EntireSubtree || this.hasWildcard)
            {
                return(entityType.StructuralProperties().Where(sp => sp.Type.IsStream()).ToDictionary(sp => sp.Name, StringComparer.Ordinal));
            }

            Debug.Assert(this.selectedProperties != null, "selectedProperties != null");

            IDictionary <string, IEdmStructuralProperty> selectedStreamProperties = this.selectedProperties
                                                                                    .Select(entityType.FindProperty)
                                                                                    .OfType <IEdmStructuralProperty>()
                                                                                    .Where(p => p.Type.IsStream())
                                                                                    .ToDictionary(p => p.Name, StringComparer.Ordinal);

            // gather up the selected stream from any child nodes that have type segments matching the current type and add them to the dictionary.
            foreach (SelectedPropertiesNode typeSegmentChild in this.GetMatchingTypeSegments(entityType))
            {
                var streamPropertiesForTypeSegment = typeSegmentChild.GetSelectedStreamProperties(entityType);
                foreach (var kvp in streamPropertiesForTypeSegment)
                {
                    selectedStreamProperties[kvp.Key] = kvp.Value;
                }
            }

            return(selectedStreamProperties);
        }
コード例 #28
0
ファイル: UpdateTests.cs プロジェクト: larsenjo/odata.net
 private void CompareEntityWithPayload(XmlDocument document, object expectedInstance, IEdmEntityType entityType, string responseFormat)
 {
     foreach (var property in entityType.StructuralProperties())
     {
         PropertyInfo propertyInfo = expectedInstance.GetType().GetProperty(property.Name);
         Type propertyType = propertyInfo.PropertyType;
         propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;
         object expectedValue = propertyInfo.GetValue(expectedInstance, null);
         ComparePropertyValue(document, propertyInfo, responseFormat, expectedValue);
     }
 }
コード例 #29
0
ファイル: UpdateTests.cs プロジェクト: larsenjo/odata.net
            private void PopulateResource(IEdmEntityType entityType, Dictionary<Type, TypeData> sampleValues, object instance, int index)
            {
                var properties = entityType.StructuralProperties().ToList();
                for (int i = 0; i < properties.Count; i++)
                {
                    IEdmProperty property = properties[i];
                    PropertyInfo propertyInfo = instance.GetType().GetProperty(property.Name);
                    Type propertyType = propertyInfo.PropertyType;
                    propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;
                    TypeData sampleValueForType = sampleValues[propertyType];
                    object propertyValue;
                    if (index < sampleValueForType.SampleValues.Length)
                    {
                        propertyValue = sampleValueForType.SampleValues[index];
                    }
                    else
                    {
                        propertyValue = sampleValueForType.SampleValues[sampleValueForType.SampleValues.Length - 1];
                    }

                    // set the property value
                    propertyInfo.SetValue(instance, propertyValue, null);
                }
            }
コード例 #30
0
        private void CompareEntityType(IEdmEntityType expectedEntityType, IEdmEntityType actualEntityType)
        {
            this.SatisfiesEquals(expectedEntityType.FullName(), actualEntityType.FullName(), "EntityType name does not match.");
            this.SatisfiesEquals(expectedEntityType.IsAbstract, actualEntityType.IsAbstract, "IsAbstract does not match for EntityType '{0}'.", expectedEntityType.FullName());

            string expectedBaseTypeName = expectedEntityType.BaseType != null ? ((IEdmSchemaElement)expectedEntityType.BaseType).FullName() : null;
            string actualBaseTypeName = actualEntityType.BaseType != null ? ((IEdmSchemaElement)actualEntityType.BaseType).FullName() : null;

            this.SatisfiesEquals(expectedBaseTypeName, actualBaseTypeName, "BaseType does not match for EntityType '{0}'.", expectedEntityType.FullName());
            this.CompareProperties(expectedEntityType.StructuralProperties().Cast<IEdmProperty>(), actualEntityType.StructuralProperties().Cast<IEdmProperty>());
            this.CompareProperties(expectedEntityType.Key().OfType<IEdmProperty>(), actualEntityType.Key().OfType<IEdmProperty>());
            this.CompareNavigationProperty(expectedEntityType.Properties().OfType<IEdmNavigationProperty>(), actualEntityType.Properties().OfType<IEdmNavigationProperty>());

            this.CompareTermAnnotations(expectedEntityType, actualEntityType);
        }
コード例 #31
0
        /// <summary>
        /// Creates a new instance of the <see cref="SelectExpandNode"/> class describing the set of structural properties,
        /// navigation properties, and actions to select and expand for the given <paramref name="selectExpandClause"/>.
        /// </summary>
        /// <param name="selectExpandClause">The parsed $select and $expand query options.</param>
        /// <param name="entityType">The entity type of the entry that would be written.</param>
        /// <param name="model">The <see cref="IEdmModel"/> that contains the given entity type.</param>
        public SelectExpandNode(SelectExpandClause selectExpandClause, IEdmEntityType entityType, IEdmModel model)
            : this()
        {
            if (entityType == null)
            {
                throw Error.ArgumentNull("entityType");
            }
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            HashSet <IEdmStructuralProperty> allStructuralProperties = new HashSet <IEdmStructuralProperty>(entityType.StructuralProperties());
            HashSet <IEdmNavigationProperty> allNavigationProperties = new HashSet <IEdmNavigationProperty>(entityType.NavigationProperties());
            HashSet <IEdmAction>             allActions   = new HashSet <IEdmAction>(model.GetAvailableActions(entityType));
            HashSet <IEdmFunction>           allFunctions = new HashSet <IEdmFunction>(model.GetAvailableFunctions(entityType));

            if (selectExpandClause == null)
            {
                SelectedStructuralProperties = allStructuralProperties;
                SelectedNavigationProperties = allNavigationProperties;
                SelectedActions            = allActions;
                SelectedFunctions          = allFunctions;
                SelectAllDynamicProperties = true;
            }
            else
            {
                if (selectExpandClause.AllSelected)
                {
                    SelectedStructuralProperties = allStructuralProperties;
                    SelectedNavigationProperties = allNavigationProperties;
                    SelectedActions            = allActions;
                    SelectedFunctions          = allFunctions;
                    SelectAllDynamicProperties = true;
                }
                else
                {
                    BuildSelections(selectExpandClause, allStructuralProperties, allNavigationProperties, allActions, allFunctions);
                    SelectAllDynamicProperties = false;
                }

                BuildExpansions(selectExpandClause, allNavigationProperties);

                // remove expanded navigation properties from the selected navigation properties.
                SelectedNavigationProperties.ExceptWith(ExpandedNavigationProperties.Keys);
            }
        }
コード例 #32
0
ファイル: JsonValidator.cs プロジェクト: larsenjo/odata.net
        internal static string GetJsonPayload(IEdmEntityType entityType, object value)
        {
            Type valueType = value.GetType();
            StringBuilder sb = new StringBuilder();
            sb.Append("{");
            sb.Append(Environment.NewLine);
            sb.Append("\t");
            sb.Append("@odata.type: \"" + entityType.FullName() + "\",");
            var properties = entityType.StructuralProperties().ToList();
            for (int i = 0; i < properties.Count; i++)
            {
                sb.Append("\t");
                IEdmProperty property = properties[i];
                // Type propertyType = ((PrimitiveType)property.TypeUsage.EdmType).ClrEquivalentType;
                PropertyInfo propertyInfo = valueType.GetProperty(property.Name);
                Type propertyType = propertyInfo.PropertyType;
                propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;            
                object propertyValue = propertyInfo.GetValue(value, null);
                sb.Append(String.Format("{0}:{1}", properties[i].Name, PrimitiveToString(propertyValue, propertyType)));
                if (i != properties.Count - 1)
                {
                    sb.Append(",");
                }
                sb.Append(Environment.NewLine);
            }
            sb.Append("}");

            return sb.ToString();
        }
コード例 #33
0
        internal AndConstraint <SelectedPropertiesNodeAssertions> IncludeEntireSubtree(IEdmEntityType entityType)
        {
            this.Subject.As <SelectedPropertiesNode>().GetSelectedStreamProperties(entityType).Values.Should().BeEquivalentTo(entityType.StructuralProperties().Where(p => p.Type.IsStream()));
            this.Subject.As <SelectedPropertiesNode>().GetSelectedNavigationProperties(entityType).Should().BeEquivalentTo(entityType.NavigationProperties());

            foreach (var navigation in entityType.NavigationProperties())
            {
                this.Subject.As <SelectedPropertiesNode>().GetSelectedPropertiesForNavigationProperty(entityType, navigation.Name).Should().HaveEntireSubtree();
            }

            return(new AndConstraint <SelectedPropertiesNodeAssertions>(this));
        }
コード例 #34
0
        // new CollectionWrapper<ElementType> { Instance = source.Select((ElementType element) => new Wrapper { }) }
        private Expression ProjectCollection(Expression source, Type elementType, SelectExpandClause selectExpandClause, IEdmEntityType entityType, IEdmNavigationSource navigationSource, ExpandedNavigationSelectItem expandedItem, int?modelBoundPageSize)
        {
            ParameterExpression element = Expression.Parameter(elementType);

            // expression
            //      new Wrapper { }
            Expression projection = ProjectElement(element, selectExpandClause, entityType, navigationSource);

            // expression
            //      (ElementType element) => new Wrapper { }
            LambdaExpression selector = Expression.Lambda(projection, element);

            if (expandedItem != null)
            {
                source = AddOrderByQueryForSource(source, expandedItem.OrderByOption, elementType);
            }

            if (_settings.PageSize.HasValue || modelBoundPageSize.HasValue ||
                (expandedItem != null && (expandedItem.TopOption.HasValue || expandedItem.SkipOption.HasValue)))
            {
                // nested paging. Need to apply order by first, and take one more than page size as we need to know
                // whether the collection was truncated or not while generating next page links.
                IEnumerable <IEdmStructuralProperty> properties =
                    entityType.Key().Any()
                        ? entityType.Key()
                        : entityType
                    .StructuralProperties()
                    .Where(property => property.Type.IsPrimitive() && !property.Type.IsStream())
                    .OrderBy(property => property.Name);

                if (expandedItem == null || expandedItem.OrderByOption == null)
                {
                    bool alreadyOrdered = false;
                    foreach (var prop in properties)
                    {
                        source = ExpressionHelpers.OrderByPropertyExpression(source, prop.Name, elementType,
                                                                             alreadyOrdered);
                        if (!alreadyOrdered)
                        {
                            alreadyOrdered = true;
                        }
                    }
                }

                if (expandedItem != null && expandedItem.SkipOption.HasValue)
                {
                    Contract.Assert(expandedItem.SkipOption.Value <= Int32.MaxValue);
                    source = ExpressionHelpers.Skip(source, (int)expandedItem.SkipOption.Value, elementType,
                                                    _settings.EnableConstantParameterization);
                }

                if (expandedItem != null && expandedItem.TopOption.HasValue)
                {
                    Contract.Assert(expandedItem.TopOption.Value <= Int32.MaxValue);
                    source = ExpressionHelpers.Take(source, (int)expandedItem.TopOption.Value, elementType,
                                                    _settings.EnableConstantParameterization);
                }

                if (_settings.PageSize.HasValue)
                {
                    source = ExpressionHelpers.Take(source, _settings.PageSize.Value + 1, elementType,
                                                    _settings.EnableConstantParameterization);
                }
                else if (_settings.ModelBoundPageSize.HasValue)
                {
                    source = ExpressionHelpers.Take(source, modelBoundPageSize.Value + 1, elementType,
                                                    _settings.EnableConstantParameterization);
                }
            }

            // expression
            //      source.Select((ElementType element) => new Wrapper { })
            Expression selectedExpresion = Expression.Call(GetSelectMethod(elementType, projection.Type), source, selector);

            if (_settings.HandleNullPropagation == HandleNullPropagationOption.True)
            {
                // source == null ? null : projectedCollection
                return(Expression.Condition(
                           test: Expression.Equal(source, Expression.Constant(null)),
                           ifTrue: Expression.Constant(null, selectedExpresion.Type),
                           ifFalse: selectedExpresion));
            }
            else
            {
                return(selectedExpresion);
            }
        }
コード例 #35
0
 private IEdmStructuralProperty GetStructuralProperty(IEdmEntityType entityType, string identifier)
 {
     return(entityType.StructuralProperties().FirstOrDefault(x => x.Name.Equals(identifier)));
 }
コード例 #36
0
        internal AndConstraint<SelectedPropertiesNodeAssertions> IncludeEntireSubtree(IEdmEntityType entityType)
        {
            this.Subject.As<SelectedPropertiesNode>().GetSelectedStreamProperties(entityType).Values.Should().BeEquivalentTo(entityType.StructuralProperties().Where(p => p.Type.IsStream()));
            this.Subject.As<SelectedPropertiesNode>().GetSelectedNavigationProperties(entityType).Should().BeEquivalentTo(entityType.NavigationProperties());

            foreach (var navigation in entityType.NavigationProperties())
            {
                this.Subject.As<SelectedPropertiesNode>().GetSelectedPropertiesForNavigationProperty(entityType, navigation.Name).Should().BeSameAsEntireSubtree();
            }

            return new AndConstraint<SelectedPropertiesNodeAssertions>(this);
        }
コード例 #37
0
        /// <summary>
        /// Gets the selected stream properties for the current node.
        /// </summary>
        /// <param name="entityType">The current entity type.</param>
        /// <returns>The selected stream properties.</returns>
        internal IDictionary<string, IEdmStructuralProperty> GetSelectedStreamProperties(IEdmEntityType entityType)
        {
            if (this.selectionType == SelectionType.Empty)
            {
                return EmptyStreamProperties;
            }

            // We cannot determine the selected stream properties without the user model. This means we won't be computing the missing stream properties.
            // For reading we will report what's on the wire and for writing we just write what the user explicitely told us to write.
            if (entityType == null)
            {
                return EmptyStreamProperties;
            }

            if (this.selectionType == SelectionType.EntireSubtree || this.hasWildcard)
            {
                return entityType.StructuralProperties().Where(sp => sp.Type.IsStream()).ToDictionary(sp => sp.Name, StringComparer.Ordinal);
            }

            Debug.Assert(this.selectedProperties != null, "selectedProperties != null");

            IDictionary<string, IEdmStructuralProperty> selectedStreamProperties = this.selectedProperties
                .Select(entityType.FindProperty)
                .OfType<IEdmStructuralProperty>()
                .Where(p => p.Type.IsStream())
                .ToDictionary(p => p.Name, StringComparer.Ordinal);

            // gather up the selected stream from any child nodes that have type segments matching the current type and add them to the dictionary.
            foreach (SelectedPropertiesNode typeSegmentChild in this.GetMatchingTypeSegments(entityType))
            {
                var streamPropertiesForTypeSegment = typeSegmentChild.GetSelectedStreamProperties(entityType);
                foreach (var kvp in streamPropertiesForTypeSegment)
                {
                    selectedStreamProperties[kvp.Key] = kvp.Value;
                }
            }

            return selectedStreamProperties;
        }
コード例 #38
0
ファイル: EdmLibHelpers.cs プロジェクト: baronhq/IISManager
 public static IEnumerable <IEdmStructuralProperty> GetConcurrencyProperties(this IEdmEntityType type)
 {
     return(type.StructuralProperties()
            .Where(s => s.ConcurrencyMode == EdmConcurrencyMode.Fixed && s.Type.IsPrimitive()));
 }
        private void VerifyMediaEntityGetOperation(string annotation, bool enableOperationId, bool useHTTPStatusCodeClass2XX)
        {
            // Arrange
            IEdmModel model = GetEdmModel(annotation);
            OpenApiConvertSettings settings = new OpenApiConvertSettings
            {
                EnableOperationId         = enableOperationId,
                UseSuccessStatusCodeRange = useHTTPStatusCodeClass2XX
            };

            ODataContext  context = new ODataContext(model, settings);
            IEdmEntitySet todos   = model.EntityContainer.FindEntitySet("Todos");
            IEdmSingleton me      = model.EntityContainer.FindSingleton("me");

            Assert.NotNull(todos);
            Assert.NotNull(me);

            IEdmEntityType         todo = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "Todo");
            IEdmStructuralProperty sp   = todo.StructuralProperties().First(c => c.Name == "Logo");
            ODataPath path = new ODataPath(new ODataNavigationSourceSegment(todos),
                                           new ODataKeySegment(todos.EntityType()),
                                           new ODataStreamPropertySegment(sp.Name));

            IEdmEntityType         user        = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "user");
            IEdmNavigationProperty navProperty = user.NavigationProperties().First(c => c.Name == "photo");
            ODataPath path2 = new ODataPath(new ODataNavigationSourceSegment(me),
                                            new ODataNavigationPropertySegment(navProperty),
                                            new ODataStreamContentSegment());

            // Act
            var getOperation  = _operationalHandler.CreateOperation(context, path);
            var getOperation2 = _operationalHandler.CreateOperation(context, path2);

            // Assert
            Assert.NotNull(getOperation);
            Assert.NotNull(getOperation2);
            Assert.Equal("Get Logo for Todo from Todos", getOperation.Summary);
            Assert.Equal("Get media content for the navigation property photo from me", getOperation2.Summary);
            Assert.NotNull(getOperation.Tags);
            Assert.NotNull(getOperation2.Tags);

            var tag  = Assert.Single(getOperation.Tags);
            var tag2 = Assert.Single(getOperation2.Tags);

            Assert.Equal("Todos.Todo", tag.Name);
            Assert.Equal("me.profilePhoto", tag2.Name);

            Assert.NotNull(getOperation.Responses);
            Assert.NotNull(getOperation2.Responses);
            Assert.Equal(2, getOperation.Responses.Count);
            Assert.Equal(2, getOperation2.Responses.Count);
            var statusCode = useHTTPStatusCodeClass2XX ? Constants.StatusCodeClass2XX : Constants.StatusCode200;

            Assert.Equal(new[] { statusCode, "default" }, getOperation.Responses.Select(r => r.Key));
            Assert.Equal(new[] { statusCode, "default" }, getOperation2.Responses.Select(r => r.Key));

            if (!string.IsNullOrEmpty(annotation))
            {
                Assert.Equal(2, getOperation.Responses[statusCode].Content.Keys.Count);
                Assert.True(getOperation.Responses[statusCode].Content.ContainsKey("image/png"));
                Assert.True(getOperation.Responses[statusCode].Content.ContainsKey("image/jpeg"));
                Assert.Equal("The logo image.", getOperation.Description);

                Assert.Equal(1, getOperation2.Responses[statusCode].Content.Keys.Count);
                Assert.True(getOperation2.Responses[statusCode].Content.ContainsKey(Constants.ApplicationOctetStreamMediaType));
            }
            else
            {
                Assert.Equal(1, getOperation.Responses[statusCode].Content.Keys.Count);
                Assert.Equal(1, getOperation2.Responses[statusCode].Content.Keys.Count);
                Assert.True(getOperation.Responses[statusCode].Content.ContainsKey(Constants.ApplicationOctetStreamMediaType));
                Assert.True(getOperation2.Responses[statusCode].Content.ContainsKey(Constants.ApplicationOctetStreamMediaType));
            }

            if (enableOperationId)
            {
                Assert.Equal("Todos.Todo.GetLogo", getOperation.OperationId);
                Assert.Equal("me.GetPhotoContent", getOperation2.OperationId);
            }
            else
            {
                Assert.Null(getOperation.OperationId);
                Assert.Null(getOperation2.OperationId);
            }
        }