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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } } }
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); }
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); }
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 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); }
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); }
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(); }
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)); }
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); } } }
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); }
/// <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 }); }
/// <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); } }
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); }
/// <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 }); }
/// <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()); }
// <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 }); }
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(); } }
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); }
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; }
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; }
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); }