示例#1
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);
        }
        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
        internal static bool ContainsProperty(this IEdmType type, IEdmProperty property)
        {
            Func <IEdmProperty, bool>           predicate = null;
            Func <IEdmProperty, bool>           func2     = null;
            Func <IEdmNavigationProperty, bool> func3     = null;
            IEdmComplexType type2 = type as IEdmComplexType;

            if (type2 != null)
            {
                if (predicate == null)
                {
                    predicate = p => p == property;
                }
                return(type2.Properties().Any <IEdmProperty>(predicate));
            }
            IEdmEntityType type3 = type as IEdmEntityType;

            if (type3 == null)
            {
                return(false);
            }
            if (func2 == null)
            {
                func2 = p => p == property;
            }
            if (type3.Properties().Any <IEdmProperty>(func2))
            {
                return(true);
            }
            if (func3 == null)
            {
                func3 = p => p == property;
            }
            return(type3.NavigationProperties().Any <IEdmNavigationProperty>(func3));
        }
        public void GenerateNavigationLink_WorksToGenerateExpectedNavigationLink_ForNonContainedNavigation()
        {
            // Arrange
            IEdmEntityType         myOrder            = (IEdmEntityType)_model.Model.FindDeclaredType("NS.MyOrder");
            IEdmNavigationProperty orderLinesProperty = myOrder.NavigationProperties().Single(x => x.Name.Equals("NonContainedOrderLines"));

            IEdmEntitySet entitySet = _model.Model.FindDeclaredEntitySet(("MyOrders"));
            IDictionary <string, object> parameters = new Dictionary <string, object>
            {
                { "ID", 42 }
            };

            IDictionary <string, object> parameters2 = new Dictionary <string, object>
            {
                { "ID", 21 }
            };

            ODataPath path = new ODataPath(
                new EntitySetSegment(entitySet),
                new KeySegment(parameters.ToArray(), myOrder, entitySet),
                new NavigationPropertySegment(orderLinesProperty, _model.NonContainedOrderLines),
                new KeySegment(parameters2.ToArray(), _model.OrderLine, _model.NonContainedOrderLines));

            var request           = RequestFactory.CreateFromModel(_model.Model);
            var serializerContext = ODataSerializerContextFactory.Create(_model.Model, _model.OrderLines, path, request);
            var entityContext     = new ResourceContext(serializerContext, _model.OrderLine.AsReference(), new { ID = 21 });

            // Act
            Uri uri = entityContext.GenerateSelfLink(false);

            // Assert
            Assert.Equal("http://localhost/OrderLines(21)", uri.AbsoluteUri);
        }
        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);
                }
            }
        }
        private IEdmNavigationProperty ComputePartner()
        {
            var            partnerPropertyPath = this.navigationProperty.PartnerPath;
            IEdmEntityType targetEntityType    = this.TargetEntityType;

            if (partnerPropertyPath != null)
            {
                return(ResolvePartnerPath(targetEntityType, partnerPropertyPath, Model)
                       ?? new UnresolvedNavigationPropertyPath(targetEntityType, partnerPropertyPath.Path, Location));
            }

            foreach (IEdmNavigationProperty potentialPartner in targetEntityType.NavigationProperties())
            {
                if (potentialPartner == this)
                {
                    continue;
                }

                if (potentialPartner.Partner == this)
                {
                    return(potentialPartner);
                }
            }

            return(null);
        }
示例#7
0
        public override bool TryTranslate(ODataTemplateTranslateContext context)
        {
            if (!context.RouteValues.TryGetValue("navigation", out object navigationNameObj))
            {
                return(false);
            }

            string         navigationName = navigationNameObj as string;
            KeySegment     keySegment     = context.Segments.Last() as KeySegment;
            IEdmEntityType entityType     = keySegment.EdmType as IEdmEntityType;

            IEdmNavigationProperty navigationProperty = entityType.NavigationProperties().FirstOrDefault(n => n.Name == navigationName);

            if (navigationProperty != null)
            {
                var navigationSource = keySegment.NavigationSource;
                IEdmNavigationSource targetNavigationSource = navigationSource.FindNavigationTarget(navigationProperty);

                NavigationPropertySegment seg = new NavigationPropertySegment(navigationProperty, navigationSource);
                context.Segments.Add(seg);
                return(true);
            }

            return(false);
        }
示例#8
0
        private bool ContainsAutoExpandProperty(object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)
        {
            Type elementClrType = GetElementType(response, actionDescriptor);

            IEdmModel model = GetModel(elementClrType, request, actionDescriptor);

            if (model == null)
            {
                throw Error.InvalidOperation(SRResources.QueryGetModelMustNotReturnNull);
            }

            IEdmEntityType entityType = model.GetEdmType(elementClrType) as IEdmEntityType;

            if (entityType != null)
            {
                var navigationProperties = entityType.NavigationProperties();
                if (navigationProperties != null)
                {
                    foreach (var navigationProperty in navigationProperties)
                    {
                        if (EdmLibHelpers.IsAutoExpand(navigationProperty, model))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
示例#9
0
        public void GenerateNavigationLink_WorksToGenerateExpectedNavigationLink_ForContainedNavigation(
            bool includeCast,
            string expectedNavigationLink)
        {
            // NOTE: This test is generating a link that does not technically correspond to a valid model (specifically
            //       the extra OrderLines navigation), but it allows us to validate the nested navigation scenario
            //       without twisting the model unnecessarily.

            // Arrange
            IEdmEntityType         myOrder            = (IEdmEntityType)_model.Model.FindDeclaredType("NS.MyOrder");
            IEdmNavigationProperty orderLinesProperty = myOrder.NavigationProperties().Single(x => x.ContainsTarget);

            var serializerContext = new ODataSerializerContext
            {
                Model            = _model.Model,
                NavigationSource = _model.OrderLines,
                Path             = new ODataPath(
                    new EntitySetPathSegment(_model.Model.FindDeclaredEntitySet("MyOrders")),
                    new KeyValuePathSegment("42"),
                    new NavigationPathSegment(orderLinesProperty),
                    new KeyValuePathSegment("21")),
                Url = GetODataRequest(_model.Model).GetUrlHelper(),
            };
            var entityContext = new EntityInstanceContext(serializerContext, _model.OrderLine.AsReference(), new { ID = 21 });

            // Act
            Uri uri = entityContext.GenerateNavigationPropertyLink(orderLinesProperty, includeCast);

            // Assert
            Assert.Equal(expectedNavigationLink, uri.AbsoluteUri);
        }
示例#10
0
        public void GenerateNavigationLink_WorksToGenerateExpectedNavigationLink_ForNonContainedNavigation()
        {
            // Arrange
            IEdmEntityType         myOrder            = (IEdmEntityType)_model.Model.FindDeclaredType("NS.MyOrder");
            IEdmNavigationProperty orderLinesProperty = myOrder.NavigationProperties().Single(x => x.Name.Equals("NonContainedOrderLines"));

            var serializerContext = new ODataSerializerContext
            {
                Model            = _model.Model,
                NavigationSource = _model.OrderLines,
                Path             = new ODataPath(
                    new EntitySetPathSegment(_model.Model.FindDeclaredEntitySet("MyOrders")),
                    new KeyValuePathSegment("42"),
                    new NavigationPathSegment(orderLinesProperty),
                    new KeyValuePathSegment("21")),
                Url = GetODataRequest(_model.Model).GetUrlHelper(),
            };
            var entityContext = new EntityInstanceContext(serializerContext, _model.OrderLine.AsReference(), new { ID = 21 });

            // Act
            Uri uri = entityContext.GenerateSelfLink(false);

            // Assert
            Assert.Equal("http://localhost/OrderLines(21)", uri.AbsoluteUri);
        }
示例#11
0
        private IEdmNavigationProperty ComputePartner()
        {
            string partnerPropertyName = this.navigationProperty.Partner;

            IEdmEntityType targetEntityType = this.TargetEntityType;

            if (partnerPropertyName != null)
            {
                var partner = targetEntityType.FindProperty(partnerPropertyName) as IEdmNavigationProperty;

                if (partner == null)
                {
                    partner = new UnresolvedNavigationPropertyPath(targetEntityType, partnerPropertyName, this.Location);
                }

                return(partner);
            }

            foreach (IEdmNavigationProperty potentialPartner in targetEntityType.NavigationProperties())
            {
                if (potentialPartner == this)
                {
                    continue;
                }

                if (potentialPartner.Partner == this)
                {
                    return(potentialPartner);
                }
            }

            return(null);
        }
示例#12
0
        private static void Build(IEdmModel edmModel, OeModelBoundSettingsBuilder modelBoundSettingsBuilder, int pageSize, bool navigationNextLink)
        {
            if (edmModel.EntityContainer != null)
            {
                foreach (IEdmEntitySet entitySet in edmModel.EntityContainer.EntitySets())
                {
                    IEdmEntityType entityType = entitySet.EntityType();
                    modelBoundSettingsBuilder.SetPageSize(pageSize, entityType);

                    foreach (IEdmNavigationProperty navigationProperty in entityType.NavigationProperties())
                    {
                        if (navigationProperty.Type.IsCollection())
                        {
                            if (navigationNextLink)
                            {
                                modelBoundSettingsBuilder.SetNavigationNextLink(navigationNextLink, navigationProperty);
                            }
                        }
                    }
                }
            }

            foreach (IEdmModel refModel in edmModel.ReferencedModels)
            {
                Build(refModel, modelBoundSettingsBuilder, pageSize, navigationNextLink);
            }
        }
        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);
                }
            }
        }
示例#14
0
        public void CreateComplexTypeWith_OneToOneOrZero_NavigationProperty()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();

            builder.EntityType <Customer>().HasKey(c => c.CustomerId);

            ComplexTypeConfiguration <Order> order = builder.ComplexType <Order>();

            order.HasOptional(o => o.Customer);

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmEntityType customerType = Assert.Single(model.SchemaElements.OfType <IEdmEntityType>());

            Assert.Equal("System.Web.OData.Builder.TestModels.Customer", customerType.FullName());
            Assert.Equal("CustomerId", customerType.DeclaredKey.Single().Name);
            Assert.Equal(1, customerType.DeclaredProperties.Count());
            Assert.Empty(customerType.NavigationProperties());

            IEdmComplexType orderType = Assert.Single(model.SchemaElements.OfType <IEdmComplexType>());

            Assert.Equal("System.Web.OData.Builder.TestModels.Order", orderType.FullName());

            IEdmNavigationProperty navProperty = Assert.Single(orderType.NavigationProperties());

            Assert.Equal(EdmMultiplicity.ZeroOrOne, navProperty.TargetMultiplicity());
            Assert.Equal("Customer", navProperty.Name);
            Assert.True(navProperty.Type.IsEntity());
            Assert.Same(customerType, navProperty.Type.Definition);
        }
示例#15
0
        public void CreateComplexTypeWith_OneToMany_NavigationProperty()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();

            builder.EntityType <Order>().HasKey(o => o.OrderId);

            ComplexTypeConfiguration <Customer> customer = builder.ComplexType <Customer>();

            customer.HasMany(c => c.Orders);

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmEntityType orderType = Assert.Single(model.SchemaElements.OfType <IEdmEntityType>());

            Assert.Equal("Microsoft.AspNet.OData.Test.Builder.TestModels.Order", orderType.FullName());
            Assert.Equal("OrderId", orderType.DeclaredKey.Single().Name);
            Assert.Single(orderType.DeclaredProperties);
            Assert.Empty(orderType.NavigationProperties());

            IEdmComplexType customerType = Assert.Single(model.SchemaElements.OfType <IEdmComplexType>());

            Assert.Equal("Microsoft.AspNet.OData.Test.Builder.TestModels.Customer", customerType.FullName());

            IEdmNavigationProperty navProperty = Assert.Single(customerType.NavigationProperties());

            Assert.Equal(EdmMultiplicity.Many, navProperty.TargetMultiplicity());
            Assert.Equal("Orders", navProperty.Name);
            Assert.True(navProperty.Type.IsCollection());
            Assert.Same(orderType, navProperty.Type.AsCollection().ElementType().Definition);
        }
示例#16
0
        internal static bool TypeIndirectlyContainsTarget(IEdmEntityType source, IEdmEntityType target, HashSetInternal <IEdmEntityType> visited, IEdmModel context)
        {
            if (visited.Add(source))
            {
                if (source.IsOrInheritsFrom(target))
                {
                    return(true);
                }

                foreach (IEdmNavigationProperty navProp in source.NavigationProperties())
                {
                    if (navProp.ContainsTarget && TypeIndirectlyContainsTarget(navProp.ToEntityType(), target, visited, context))
                    {
                        return(true);
                    }
                }

                foreach (IEdmStructuredType derived in context.FindAllDerivedTypes(source))
                {
                    IEdmEntityType derivedEntity = derived as IEdmEntityType;
                    if (derivedEntity != null && TypeIndirectlyContainsTarget(derivedEntity, target, visited, context))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
示例#17
0
        /// <summary>
        /// Gets the navigation property with the specified name.
        /// </summary>
        /// <param name="entityType">The entity type to search for navigation properties on.</param>
        /// <param name="navigationPropertyName">The navigation property name.</param>
        /// <returns>The navigation property with the specified name or null if none exists.</returns>
        public static IEdmNavigationProperty GetNavigationProperty(this IEdmEntityType entityType, string navigationPropertyName)
        {
            ExceptionUtilities.CheckArgumentNotNull(entityType, "entityType");
            ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(navigationPropertyName, "navigationPropertyName");

            return(entityType.NavigationProperties().SingleOrDefault(np => np.Name == navigationPropertyName));
        }
        /// <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);
        }
        public void Ctor_ThatBuildsNestedContext_InitializesRightValues()
        {
            // Arrange
            IEdmEntitySet          orders       = _model.EntityContainer.FindEntitySet("Orders");
            IEdmEntitySet          customers    = _model.EntityContainer.FindEntitySet("Customers");
            IEdmEntityType         customer     = _model.SchemaElements.OfType <IEdmEntityType>().FirstOrDefault(c => c.Name == "SerializerCustomer");
            SelectExpandClause     selectExpand = new SelectExpandClause(new SelectItem[0], allSelected: true);
            IEdmNavigationProperty navProp      = customer.NavigationProperties().First();
            ODataSerializerContext context      = new ODataSerializerContext {
                NavigationSource = customers, Model = _model
            };
            ResourceContext resource = new ResourceContext {
                SerializerContext = context
            };

            // Act
            ODataSerializerContext nestedContext = new ODataSerializerContext(resource, selectExpand, navProp);

            // Assert
            Assert.Same(resource, nestedContext.ExpandedResource);
            Assert.Same(navProp, nestedContext.NavigationProperty);
            Assert.Same(selectExpand, nestedContext.SelectExpandClause);
            Assert.Same(orders, nestedContext.NavigationSource);
            Assert.Same(navProp, nestedContext.EdmProperty);
        }
示例#20
0
        internal AndConstraint <SelectedPropertiesNodeAssertions> NotHaveNavigations(IEdmEntityType entityType)
        {
            this.Subject.As <SelectedPropertiesNode>().GetSelectedNavigationProperties(entityType).Should().BeEmpty();

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

            return(new AndConstraint <SelectedPropertiesNodeAssertions>(this));
        }
        public override Task <int> SaveChangesAsync(Object dataContext, CancellationToken cancellationToken)
        {
            foreach (InMemoryEntitySetAdapter entitySetAdapter in base.EntitySetAdapters)
            {
                if (!entitySetAdapter.IsDbQuery)
                {
                    foreach (PropertyInfo key in ModelBuilder.OeModelBuilderHelper.GetKeyProperties(entitySetAdapter.EntityType))
                    {
                        if (key.PropertyType == typeof(int))
                        {
                            foreach (Object entity in entitySetAdapter.GetSource(dataContext))
                            {
                                var id = (int)key.GetValue(entity);
                                if (id < 0)
                                {
                                    key.SetValue(entity, -id);
                                }
                            }
                        }
                    }

                    IEdmEntityType entityType = OeEdmClrHelper.GetEntitySet(_edmModel, entitySetAdapter.EntitySetName).EntityType();
                    foreach (IEdmNavigationProperty navigationProperty in entityType.NavigationProperties())
                    {
                        IEnumerable <IEdmStructuralProperty> edmProperties = navigationProperty.DependentProperties();
                        if (edmProperties != null)
                        {
                            foreach (IEdmStructuralProperty edmProperty in edmProperties)
                            {
                                if (edmProperty.DeclaringType != entityType)
                                {
                                    break;
                                }

                                PropertyInfo clrProperty = entitySetAdapter.EntityType.GetProperty(edmProperty.Name) !;
                                if (clrProperty.PropertyType == typeof(int) || clrProperty.PropertyType == typeof(int?))
                                {
                                    foreach (Object entity in entitySetAdapter.GetSource(dataContext))
                                    {
                                        var id = (int?)clrProperty.GetValue(entity);
                                        if (id < 0)
                                        {
                                            clrProperty.SetValue(entity, -id);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(base.SaveChangesAsync(dataContext, cancellationToken));
        }
        internal static SelectedPropertiesNode NotHaveNavigations(this SelectedPropertiesNode node, IEdmEntityType entityType)
        {
            Assert.Empty(node.GetSelectedNavigationProperties(entityType));

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

            return(node);
        }
示例#23
0
        public override IEnumerable <String> GetNavigationProperties(String tableName)
        {
            IEdmEntityType edmEntityType = OeEdmClrHelper.GetEntitySet(_edmModel, tableName).EntityType();

            foreach (IEdmNavigationProperty navigationProperty in edmEntityType.NavigationProperties())
            {
                if (!navigationProperty.ContainsTarget)
                {
                    yield return(navigationProperty.Name);
                }
            }
        }
        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();
        }
示例#25
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));
        }
示例#26
0
        public override IEnumerable <(String, String)> GetManyToManyProperties(String tableName)
        {
            IEdmEntityType edmEntityType = OeEdmClrHelper.GetEntitySet(_edmModel, tableName).EntityType();

            foreach (IEdmNavigationProperty navigationProperty in edmEntityType.NavigationProperties())
            {
                if (navigationProperty.ContainsTarget)
                {
                    ManyToManyJoinDescription joinDescription = _edmModel.GetManyToManyJoinDescription(navigationProperty);
                    IEdmEntitySet             targetEntitySet = OeEdmClrHelper.GetEntitySet(_edmModel, joinDescription.TargetNavigationProperty);
                    yield return(navigationProperty.Name, targetEntitySet.Name);
                }
            }
        }
示例#27
0
        public static IList <string> CreateExpandItems(this IEdmEntityType entityType)
        {
            IList <string> expandItems = new List <string>
            {
                "*"
            };

            foreach (var property in entityType.NavigationProperties())
            {
                expandItems.Add(property.Name);
            }

            return(expandItems);
        }
示例#28
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
            });
        }
示例#29
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);
            }
        }
示例#30
0
        public void Translate_NavigationPropertySegment_To_NavigationPathSegment_Works()
        {
            // Arrange
            IEdmEntitySet             entityset          = _model.FindDeclaredEntitySet("Products");
            IEdmEntityType            entityType         = _model.FindDeclaredType("System.Web.OData.Routing.RoutingCustomer") as IEdmEntityType;
            IEdmNavigationProperty    navigationProperty = entityType.NavigationProperties().First(e => e.Name == "Products");
            NavigationPropertySegment segment            = new NavigationPropertySegment(navigationProperty, entityset);

            // Act
            IEnumerable <ODataPathSegment> segments = _translator.Translate(segment);

            // Assert
            ODataPathSegment      pathSegment           = Assert.Single(segments);
            NavigationPathSegment navigationPathSegment = Assert.IsType <NavigationPathSegment>(pathSegment);

            Assert.Same(navigationProperty, navigationPathSegment.NavigationProperty);
        }
示例#31
0
        /// <summary>
        /// Create $expand parameter for the <see cref="IEdmNavigationSource"/>.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="target">The edm entity path.</param>
        /// <param name="entityType">The edm entity path.</param>
        /// <returns>The created <see cref="OpenApiParameter"/> or null.</returns>
        public static OpenApiParameter CreateExpand(this ODataContext context, IEdmVocabularyAnnotatable target, IEdmEntityType entityType)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(target, nameof(target));
            Utils.CheckArgumentNull(entityType, nameof(entityType));

            ExpandRestrictionsType expand = context.Model.GetRecord <ExpandRestrictionsType>(target, CapabilitiesConstants.ExpandRestrictions);

            if (expand != null && !expand.IsExpandable)
            {
                return(null);
            }

            IList <IOpenApiAny> expandItems = new List <IOpenApiAny>
            {
                new OpenApiString("*")
            };

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

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

            return(new OpenApiParameter
            {
                Name = "$expand",
                In = ParameterLocation.Query,
                Description = "Expand related entities",
                Schema = new OpenApiSchema
                {
                    Type = "array",
                    UniqueItems = true,
                    Items = new OpenApiSchema
                    {
                        Type = "string",
                        Enum = expandItems
                    }
                },
                Style = ParameterStyle.Form
            });
        }
示例#32
0
        /// <summary>
        /// Gets the selected navigation properties for the current node.
        /// </summary>
        /// <param name="entityType">The current entity type.</param>
        /// <returns>The set of selected navigation properties.</returns>
        internal IEnumerable <IEdmNavigationProperty> GetSelectedNavigationProperties(IEdmEntityType entityType)
        {
            DebugUtils.CheckNoExternalCallers();

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

            // We cannot determine the selected navigation properties without the user model. This means we won't be computing the missing navigation 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(EmptyNavigationProperties);
            }

            if (this.selectionType == SelectionType.EntireSubtree || this.hasWildcard)
            {
                return(entityType.NavigationProperties());
            }

            // Find all the selected navigation properties
            // NOTE: the assumption is that the number of selected properties usually is a lot smaller
            //       than the number of all properties on the type and that FindProperty for each selected
            //       property is faster than iterating through all the properties on the type.
            Debug.Assert(this.selectedProperties != null, "selectedProperties != null");
            IEnumerable <string> navigationPropertyNames = this.selectedProperties;

            if (this.children != null)
            {
                navigationPropertyNames = this.children.Keys.Concat(navigationPropertyNames);
            }

            IEnumerable <IEdmNavigationProperty> selectedNavigationProperties = navigationPropertyNames
                                                                                .Select(entityType.FindProperty)
                                                                                .OfType <IEdmNavigationProperty>();

            // gather up the selected navigations from any child nodes that have type segments matching the current type and append them.
            foreach (SelectedPropertiesNode typeSegmentChild in this.GetMatchingTypeSegments(entityType))
            {
                selectedNavigationProperties = selectedNavigationProperties.Concat(typeSegmentChild.GetSelectedNavigationProperties(entityType));
            }

            // ensure no duplicates are returned.
            return(selectedNavigationProperties.Distinct());
        }
示例#33
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
            });
        }
示例#34
0
        private static void WriteNavigationLinks(ODataWriter writer, object element, Uri parentEntryUri, IEdmEntityType parentEntityType, IEdmModel model, ODataVersion targetVersion, IEnumerable<string> expandedNavigationProperties) 
        {
            foreach (var navigationProperty in parentEntityType.NavigationProperties())
            {
                IEdmTypeReference propertyTypeReference = navigationProperty.Type;
                bool isCollection = navigationProperty.Type.IsCollection();

                var navigationLink = new ODataNavigationLink
                                         {
                                             Url = new Uri(parentEntryUri, navigationProperty.Name),
                                             IsCollection = isCollection,
                                             Name = navigationProperty.Name,
                                         };

                writer.WriteStart(navigationLink);

                if (expandedNavigationProperties.Contains(navigationProperty.Name))
                {
                    var propertyValue = DataContext.GetPropertyValue(element, navigationProperty.Name);

                    if (propertyValue != null)
                    {
                        var propertyEntityType = propertyTypeReference.Definition as IEdmEntityType;
                        IEdmEntitySet targetEntitySet = model.EntityContainer.EntitySets().Single(s => s.EntityType() == propertyEntityType);

                        if (isCollection)
                        {
                            WriteFeed(writer, propertyValue as IEnumerable, targetEntitySet, model, targetVersion, Enumerable.Empty<string>());
                        }
                        else
                        {
                            WriteEntry(writer, propertyValue, targetEntitySet, model, targetVersion, Enumerable.Empty<string>());
                        }
                    }
                }

                writer.WriteEnd();
            }
            
        }
示例#35
0
		internal static bool TypeIndirectlyContainsTarget(IEdmEntityType source, IEdmEntityType target, HashSetInternal<IEdmEntityType> visited, IEdmModel context)
		{
			bool flag;
			if (visited.Add(source))
			{
				if (!source.IsOrInheritsFrom(target))
				{
					foreach (IEdmNavigationProperty edmNavigationProperty in source.NavigationProperties())
					{
						if (!edmNavigationProperty.ContainsTarget || !ValidationHelper.TypeIndirectlyContainsTarget(edmNavigationProperty.ToEntityType(), target, visited, context))
						{
							continue;
						}
						flag = true;
						return flag;
					}
					IEnumerator<IEdmStructuredType> enumerator = context.FindAllDerivedTypes(source).GetEnumerator();
					using (enumerator)
					{
						while (enumerator.MoveNext())
						{
							IEdmStructuredType current = enumerator.Current;
							IEdmEntityType edmEntityType = current as IEdmEntityType;
							if (edmEntityType == null || !ValidationHelper.TypeIndirectlyContainsTarget(edmEntityType, target, visited, context))
							{
								continue;
							}
							flag = true;
							return flag;
						}
						return false;
					}
					return flag;
				}
				else
				{
					return true;
				}
			}
			return false;
		}
        internal AndConstraint<SelectedPropertiesNodeAssertions> NotHaveNavigations(IEdmEntityType entityType)
        {
            this.Subject.As<SelectedPropertiesNode>().GetSelectedNavigationProperties(entityType).Should().BeEmpty();

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

            return new AndConstraint<SelectedPropertiesNodeAssertions>(this);
        }
示例#37
0
        public static IEnumerable<IEdmNavigationProperty> GetAutoExpandNavigationProperties(
            IEdmEntityType entityType, IEdmModel edmModel)
        {
            List<IEdmNavigationProperty> autoExpandNavigationProperties = new List<IEdmNavigationProperty>();
            if (entityType != null)
            {
                var navigationProperties = entityType.NavigationProperties();
                if (navigationProperties != null)
                {
                    foreach (var navigationProperty in navigationProperties)
                    {
                        if (IsAutoExpand(navigationProperty, edmModel))
                        {
                            autoExpandNavigationProperties.Add(navigationProperty);
                        }
                    }
                }
            }

            return autoExpandNavigationProperties;
        }
示例#38
0
        private static IEnumerable<SelectItem> GetAutoExpandedNavigationSelectItems(
            IEdmEntityType entityType, 
            IEdmModel model,
            string alreadyExpandedNavigationSourceName,
            IEdmNavigationSource navigationSource,
            bool isAllSelected)
        {
            List<SelectItem> expandItems = new List<SelectItem>();
            if (entityType != null)
            {
                var navigationProperties = entityType.NavigationProperties();
                if (navigationProperties != null)
                {
                    foreach (var navigationProperty in navigationProperties)
                    {
                        if (!alreadyExpandedNavigationSourceName.Equals(navigationProperty.Name) &&
                            EdmLibHelpers.IsAutoExpand(navigationProperty, model))
                        {
                            IEdmNavigationSource currentEdmNavigationSource =
                                navigationSource.FindNavigationTarget(navigationProperty);
                            if (currentEdmNavigationSource != null)
                            {
                                List<ODataPathSegment> pathSegments = new List<ODataPathSegment>()
                                {
                                    new NavigationPropertySegment(navigationProperty, currentEdmNavigationSource)
                                };

                                ODataExpandPath expandPath = new ODataExpandPath(pathSegments);
                                SelectExpandClause selectExpandClause = new SelectExpandClause(new List<SelectItem>(),
                                    true);
                                ExpandedNavigationSelectItem item = new ExpandedNavigationSelectItem(expandPath,
                                    currentEdmNavigationSource, selectExpandClause);
                                if (!currentEdmNavigationSource.EntityType().Equals(entityType))
                                {
                                    IEnumerable<SelectItem> nestedSelectItems = GetAutoExpandedNavigationSelectItems(
                                        currentEdmNavigationSource.EntityType(),
                                        model,
                                        alreadyExpandedNavigationSourceName,
                                        item.NavigationSource,
                                        true);
                                    selectExpandClause = new SelectExpandClause(nestedSelectItems, true);
                                    item = new ExpandedNavigationSelectItem(expandPath, currentEdmNavigationSource,
                                        selectExpandClause);
                                }

                                expandItems.Add(item);
                                if (!isAllSelected)
                                {
                                    PathSelectItem pathSelectItem = new PathSelectItem(
                                        new ODataSelectPath(pathSegments));
                                    expandItems.Add(pathSelectItem);
                                }
                            }
                        }
                    }
                }
            }
            return expandItems;
        }
示例#39
0
        internal static bool TypeIndirectlyContainsTarget(IEdmEntityType source, IEdmEntityType target, HashSetInternal<IEdmEntityType> visited, IEdmModel context)
        {
            if (visited.Add(source))
            {
                if (source.IsOrInheritsFrom(target))
                {
                    return true;
                }

                foreach (IEdmNavigationProperty navProp in source.NavigationProperties())
                {
                    if (navProp.ContainsTarget && TypeIndirectlyContainsTarget(navProp.ToEntityType(), target, visited, context))
                    {
                        return true;
                    }
                }

                foreach (IEdmStructuredType derived in context.FindAllDerivedTypes(source))
                {
                    IEdmEntityType derivedEntity = derived as IEdmEntityType;
                    if (derivedEntity != null && TypeIndirectlyContainsTarget(derivedEntity, target, visited, context))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
        /// <summary>
        /// Gets the selected navigation properties for the current node.
        /// </summary>
        /// <param name="entityType">The current entity type.</param>
        /// <returns>The set of selected navigation properties.</returns>
        internal IEnumerable<IEdmNavigationProperty> GetSelectedNavigationProperties(IEdmEntityType entityType)
        {
            if (this.selectionType == SelectionType.Empty)
            {
                return EmptyNavigationProperties;
            }

            // We cannot determine the selected navigation properties without the user model. This means we won't be computing the missing navigation 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 EmptyNavigationProperties;
            }

            if (this.selectionType == SelectionType.EntireSubtree || this.hasWildcard)
            {
                return entityType.NavigationProperties();
            }

            // Find all the selected navigation properties
            // NOTE: the assumption is that the number of selected properties usually is a lot smaller
            //       than the number of all properties on the type and that FindProperty for each selected
            //       property is faster than iterating through all the properties on the type.
            Debug.Assert(this.selectedProperties != null, "selectedProperties != null");
            IEnumerable<string> navigationPropertyNames = this.selectedProperties;
            if (this.children != null)
            {
                navigationPropertyNames = this.children.Keys.Concat(navigationPropertyNames);
            }

            IEnumerable<IEdmNavigationProperty> selectedNavigationProperties = navigationPropertyNames
                .Select(entityType.FindProperty)
                .OfType<IEdmNavigationProperty>();

            // gather up the selected navigations from any child nodes that have type segments matching the current type and append them.
            foreach (SelectedPropertiesNode typeSegmentChild in this.GetMatchingTypeSegments(entityType))
            {
                selectedNavigationProperties = selectedNavigationProperties.Concat(typeSegmentChild.GetSelectedNavigationProperties(entityType));
            }

            // ensure no duplicates are returned.
            return selectedNavigationProperties.Distinct();
        }
        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);
        }