public void EdmPathExpression() { var e = new EdmPathExpression("x", "y"); Assert.IsFalse(e.IsBad(), "e good"); Assert.AreEqual(EdmExpressionKind.Path, e.ExpressionKind, "e.ExpressionKind"); Assert.AreEqual(2, e.Path.Count(), "e.Path.Count()"); var s1 = e.Path.First(); Assert.AreEqual("x", s1, "s1"); Assert.AreEqual("y", e.Path.Last(), "e.Path.Last()"); try { new EdmPathExpression((string[])null); Assert.Fail("exception expected"); } catch (ArgumentNullException) { } var ee = new MutablePathExpression(); Assert.IsNull(ee.Path, "ee.Path"); Assert.IsTrue(ee.IsBad(), "Expression is bad."); Assert.AreEqual(1, ee.Errors().Count(), "Expression has no errors"); }
public OpenApiRequestBodyGeneratorTest() { EdmModel model = new EdmModel(); EdmEntityContainer container = new EdmEntityContainer("NS", "Default"); model.AddElement(container); EdmEntityType customer = new EdmEntityType("NS", "Customer", null, false, false, true); customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32)); var boolType = EdmCoreModel.Instance.GetBoolean(false); var actionEntitySetPath = new EdmPathExpression("Param1/Nav"); var edmAction = new EdmAction("NS", "Checkout", boolType, true, actionEntitySetPath); edmAction.AddParameter(new EdmOperationParameter(edmAction, "bindingParameter", new EdmEntityTypeReference(customer, true))); edmAction.AddParameter("param", EdmCoreModel.Instance.GetString(true)); model.AddElement(edmAction); var actionImportEntitySetPath = new EdmPathExpression("Param1/Nav2"); var edmActionImport = new EdmActionImport(container, "CheckoutImport", edmAction, actionImportEntitySetPath); container.AddElement(edmActionImport); _model = model; _entityType = customer; _action = edmAction; _actionImport = edmActionImport; }
private static IEdmEntitySetBase GetTargetEntitySet(EdmPathExpression edmPathExpression, out IEdmEntitySet targetEntitySet, bool addParameters = false, bool isBindable = true) { var model = new EdmModel(); var container = new EdmEntityContainer("Fake", "Container"); model.AddElement(container); var edmEntityType = new EdmEntityType("Fake", "EntityType"); var sourceEntitySet = container.AddEntitySet("SourceEntitySet", edmEntityType); var middleEntitySet = container.AddEntitySet("MiddleEntitySet", edmEntityType); targetEntitySet = container.AddEntitySet("TargetEntitySet", edmEntityType); var nav1 = edmEntityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "Navigation1", Target = edmEntityType, TargetMultiplicity = EdmMultiplicity.ZeroOrOne }); var nav2 = edmEntityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "Navigation2", Target = edmEntityType, TargetMultiplicity = EdmMultiplicity.Many }); sourceEntitySet.AddNavigationTarget(nav1, middleEntitySet); middleEntitySet.AddNavigationTarget(nav2, targetEntitySet); var action = new EdmAction("Fake", "FakeAction", new EdmEntityTypeReference(edmEntityType, false), isBindable, null /*EntitySetPath*/); if (addParameters) { action.AddParameter("p1", new EdmEntityTypeReference(edmEntityType, false)); action.AddParameter("p2", new EdmEntityTypeReference(edmEntityType, false)); } var actionImport = container.AddActionImport("FakeAction", action, edmPathExpression); return(actionImport.GetTargetEntitySet(sourceEntitySet, model)); }
public void EnsureFunctionImportIsAddedAndWithCorrectEntitySetExpression() { EdmEntityContainer container = new EdmEntityContainer("Default", "Container"); EdmAction action = new EdmAction("DS", "TestAction", EdmCoreModel.Instance.GetBoolean(false)); var entitySetExpression = new EdmPathExpression("EntitySet"); var actionImport = container.AddActionImport("OtherName", action, entitySetExpression); Assert.Same(action, actionImport.Action); Assert.Equal("OtherName", actionImport.Name); Assert.Same(entitySetExpression, actionImport.EntitySet); Assert.Same(actionImport, container.Elements.ToArray()[0]); }
public void GetTargetEntitySetForFunctionWithNoStaticSetOrSourceSetShouldBeNull() { var model = new EdmModel(); var container = new EdmEntityContainer("Fake", "Container"); model.AddElement(container); var function = new EdmFunction("Fake", "FakeFunction", new EdmEntityTypeReference(new EdmEntityType("Fake", "EntityType"), false)); var expression = new EdmPathExpression("p1/Navigation1"); var operationImport = container.AddFunctionImport("FakeAction", function, expression); operationImport.GetTargetEntitySet(null, model).Should().BeNull(); }
public void EdmActionConstructorShouldHaveSpecifiedConstructorValues() { var entitySetPath = new EdmPathExpression("Param1/Nav"); var edmAction = new EdmAction(defaultNamespaceName, checkout, this.boolType, true, entitySetPath); edmAction.AddParameter(new EdmOperationParameter(edmAction, "Param1", new EdmEntityTypeReference(personType, false))); edmAction.Namespace.Should().Be(defaultNamespaceName); edmAction.Name.Should().Be(checkout); edmAction.ReturnType.Should().Be(this.boolType); edmAction.EntitySetPath.Should().Be(entitySetPath); edmAction.IsBound.Should().BeTrue(); edmAction.SchemaElementKind.Should().Be(EdmSchemaElementKind.Action); }
public void EdmActionImportConstructorShouldHaveSpecifiedConstructorValues() { var actionEntitySetPath = new EdmPathExpression("Param1/Nav"); var edmAction = new EdmAction("DefaultNamespace", "Checkout", this.boolType, true, actionEntitySetPath); edmAction.AddParameter(new EdmOperationParameter(edmAction, "Param1", new EdmEntityTypeReference(personType, true))); var actionImportEntitySetPath = new EdmPathExpression("Param1/Nav2"); var edmActionImport = new EdmActionImport(this.entityContainer, "checkoutImport", edmAction, actionImportEntitySetPath); edmActionImport.Name.Should().Be("checkoutImport"); edmActionImport.Container.Should().Be(this.entityContainer); edmActionImport.EntitySet.Should().Be(actionImportEntitySetPath); edmActionImport.Action.Should().Be(edmAction); }
public void EdmFunctionConstructorShouldHaveSpecifiedConstructorValues() { var entitySetPath = new EdmPathExpression("Param1/Nav"); var edmFunction = new EdmFunction(defaultNamespaceName, checkout, this.boolType, true, entitySetPath, true /*IsComposable*/); edmFunction.AddParameter(new EdmOperationParameter(edmFunction, "Param1", new EdmEntityTypeReference(personType, false))); Assert.Equal(defaultNamespaceName, edmFunction.Namespace); Assert.Equal(checkout, edmFunction.Name); Assert.Same(this.boolType, edmFunction.ReturnType); Assert.Same(entitySetPath, edmFunction.EntitySetPath); Assert.True(edmFunction.IsBound); Assert.Equal(EdmSchemaElementKind.Function, edmFunction.SchemaElementKind); Assert.True(edmFunction.IsComposable); Assert.NotNull(edmFunction.Return); Assert.Same(edmFunction.ReturnType, edmFunction.Return.Type); }
/// <summary> /// Initializes a new <see cref="IEdmOperationImport"/> instance. /// </summary> /// <param name="name">name of the service operation.</param> /// <param name="function">Function imported in.</param> /// <param name="resultSet">EntitySet of the result expected from this operation.</param> public EdmFunctionImport AddFunctionAndFunctionImport(string name, IEdmTypeReference bindingType, IEdmTypeReference resultType, IEdmEntitySet resultSet, bool isBindable) { var edmFunction = new EdmFunction(this.Namespace, name, resultType, isBindable, null, false /*isComposable*/); if (isBindable) { edmFunction.AddParameter("bindingparameter", bindingType); } IEdmPathExpression entitySetExpression = null; if (resultSet != null) { entitySetExpression = new EdmPathExpression(resultSet.Name); } this.AddOperation(edmFunction); var functionImport = new EdmFunctionImport(this, name, edmFunction, entitySetExpression, false); this.AddOperationImport(name, functionImport); return(functionImport); }
/// <summary> /// Get the string representation of <see cref="ODataPath"/>. /// mainly translate Context Url path. /// </summary> /// <param name="path">Path to perform the computation on.</param> /// <returns>The string representation of the Context Url path.</returns> public static string ToContextUrlPathString(this ODataPath path) { StringBuilder pathString = new StringBuilder(); PathSegmentToContextUrlPathTranslator pathTranslator = PathSegmentToContextUrlPathTranslator.DefaultInstance; ODataPathSegment priorSegment = null; bool foundOperationWithoutPath = false; foreach (ODataPathSegment segment in path) { OperationSegment operationSegment = segment as OperationSegment; OperationImportSegment operationImportSegment = segment as OperationImportSegment; if (operationImportSegment != null) { IEdmOperationImport operationImport = operationImportSegment.OperationImports.FirstOrDefault(); Debug.Assert(operationImport != null); EdmPathExpression pathExpression = operationImport.EntitySet as EdmPathExpression; if (pathExpression != null) { Debug.Assert(priorSegment == null); // operation import is always the first segment? pathString.Append(pathExpression.Path); } else { pathString = operationImport.Operation.ReturnType != null ? new StringBuilder(operationImport.Operation.ReturnType.FullName()) : new StringBuilder("Edm.Untyped"); foundOperationWithoutPath = true; } } else if (operationSegment != null) { IEdmOperation operation = operationSegment.Operations.FirstOrDefault(); Debug.Assert(operation != null); if (operation.IsBound && priorSegment != null && operation.Parameters.First().Type.Definition == priorSegment.EdmType) { if (operation.EntitySetPath != null) { foreach (string pathSegment in operation.EntitySetPath.PathSegments.Skip(1)) { pathString.Append('/'); pathString.Append(pathSegment); } } else if (operationSegment.EntitySet != null) { // Is it correct to check EntitySet? pathString = new StringBuilder(operationSegment.EntitySet.Name); } else { pathString = operation.ReturnType != null ? new StringBuilder(operation.ReturnType.FullName()) : new StringBuilder("Edm.Untyped"); foundOperationWithoutPath = true; } } } else { if (foundOperationWithoutPath) { pathString = new StringBuilder(segment.EdmType.FullTypeName()); foundOperationWithoutPath = false; } else { pathString.Append(segment.TranslateWith(pathTranslator)); } } priorSegment = segment; } return(pathString.ToString().TrimStart('/')); }
public EdmModel BuildEdmModel(params IEdmModel[] refModels) { AddOperations(); Dictionary <Type, EntityTypeInfo> entityTypeInfos = BuildEntityTypes(refModels); foreach (EntityTypeInfo typeInfo in entityTypeInfos.Values) { if (!typeInfo.IsRefModel) { typeInfo.BuildProperties(entityTypeInfos, _enumTypes, _complexTypes); } } foreach (EntityTypeInfo typeInfo in entityTypeInfos.Values) { foreach (FKeyInfo fkeyInfo in typeInfo.NavigationClrProperties) { fkeyInfo.EdmNavigationProperty = CreateNavigationProperty(fkeyInfo); } } var edmModel = new EdmModel(); var containers = new Dictionary <Db.OeDataAdapter, EdmEntityContainer>(); edmModel.AddElements(_enumTypes.Values); foreach (KeyValuePair <Type, EdmEnumType> enumType in _enumTypes) { edmModel.SetClrType(enumType.Value, enumType.Key); } edmModel.AddElements(_complexTypes.Values); foreach (KeyValuePair <Type, EdmComplexType> complexType in _complexTypes) { edmModel.SetClrType(complexType.Value, complexType.Key); } var container = new EdmEntityContainer(_dataAdapter.DataContextType.Namespace, _dataAdapter.DataContextType.Name); edmModel.SetDataAdapter(container, _dataAdapter); var entitySets = new Dictionary <IEdmEntityType, EdmEntitySet>(entityTypeInfos.Count); foreach (EntityTypeInfo typeInfo in entityTypeInfos.Values) { edmModel.AddElement(typeInfo.EdmType); edmModel.SetClrType(typeInfo.EdmType, typeInfo.ClrType); foreach (Db.OeEntitySetAdapter entitySetAdapter in _dataAdapter.EntitySetAdapters) { if (entitySetAdapter.EntityType == typeInfo.ClrType) { EdmEntitySet entitySet = container.AddEntitySet(entitySetAdapter.EntitySetName, typeInfo.EdmType); edmModel.SetEntitySetAdapter(entitySet, entitySetAdapter); entitySets.Add(typeInfo.EdmType, entitySet); break; } } } var manyToManyBuilder = new ManyToManyBuilder(edmModel, _metadataProvider, entityTypeInfos); foreach (EntityTypeInfo typeInfo in entityTypeInfos.Values) { foreach (FKeyInfo fkeyInfo in typeInfo.NavigationClrProperties) { EdmEntitySet principal = entitySets[fkeyInfo.PrincipalInfo.EdmType]; EdmEntitySet dependent = entitySets[fkeyInfo.DependentInfo.EdmType]; if (fkeyInfo.DependentNavigationProperty == null) { principal.AddNavigationTarget(fkeyInfo.EdmNavigationProperty, dependent); } else { dependent.AddNavigationTarget(fkeyInfo.EdmNavigationProperty, principal); if (fkeyInfo.EdmNavigationProperty.Partner != null) { principal.AddNavigationTarget(fkeyInfo.EdmNavigationProperty.Partner, dependent); } } } if (!typeInfo.IsRefModel) { manyToManyBuilder.Build(typeInfo); } } foreach (OeOperationConfiguration operationConfiguration in _operationConfigurations) { if (operationConfiguration.IsEdmFunction) { EdmPathExpression path = null; EdmFunction edmFunction = BuildFunction(operationConfiguration, entityTypeInfos); if (edmFunction.ReturnType.Definition.AsElementType() is IEdmEntityType entityType) { path = new EdmPathExpression(_dataAdapter.DataContextType.FullName, entitySets[entityType].Name); } edmModel.AddElement(edmFunction); container.AddFunctionImport(operationConfiguration.Name, edmFunction, path); edmModel.SetIsDbFunction(edmFunction, operationConfiguration.IsDbFunction); } else { EdmAction edmAction = BuildAction(operationConfiguration, entityTypeInfos); edmModel.AddElement(edmAction); container.AddActionImport(operationConfiguration.Name, edmAction); edmModel.SetIsDbFunction(edmAction, operationConfiguration.IsDbFunction); } } edmModel.AddElement(container); _dataAdapter.SetEdmModel(edmModel); foreach (IEdmModel refModel in refModels) { edmModel.AddReferencedModel(refModel); } return(edmModel); }
private void InitializeEdmModel() { this.edmModel = new EdmModel(); EdmEntityContainer defaultContainer = new EdmEntityContainer("TestModel", "DefaultContainer"); this.edmModel.AddElement(defaultContainer); addressType = new EdmComplexType("TestModel", "Address"); addressType.AddStructuralProperty("Street", EdmCoreModel.Instance.GetString(/*isNullable*/ false)); addressType.AddStructuralProperty("Zip", EdmCoreModel.Instance.GetString(/*isNullable*/ false)); this.cityType = new EdmEntityType("TestModel", "City", baseType: null, isAbstract: false, isOpen: true); EdmStructuralProperty cityIdProperty = cityType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(/*isNullable*/ false)); cityType.AddKeys(cityIdProperty); cityType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(/*isNullable*/ false)); cityType.AddStructuralProperty("Size", EdmCoreModel.Instance.GetInt32(/*isNullable*/ false)); cityType.AddStructuralProperty("Restaurants", EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetString(/*isNullable*/ false))); cityType.AddStructuralProperty("Address", new EdmComplexTypeReference(addressType, true)); this.edmModel.AddElement(cityType); this.capitolCityType = new EdmEntityType("TestModel", "CapitolCity", cityType); capitolCityType.AddStructuralProperty("CapitolType", EdmCoreModel.Instance.GetString(/*isNullable*/ false)); this.edmModel.AddElement(capitolCityType); this.districtType = new EdmEntityType("TestModel", "District"); EdmStructuralProperty districtIdProperty = districtType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(/*isNullable*/ false)); districtType.AddKeys(districtIdProperty); districtType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(/*isNullable*/ false)); districtType.AddStructuralProperty("Zip", EdmCoreModel.Instance.GetInt32(/*isNullable*/ false)); this.edmModel.AddElement(districtType); cityType.AddBidirectionalNavigation( new EdmNavigationPropertyInfo { Name = "Districts", Target = districtType, TargetMultiplicity = EdmMultiplicity.Many }, new EdmNavigationPropertyInfo { Name = "City", Target = cityType, TargetMultiplicity = EdmMultiplicity.One }); cityType.NavigationProperties().Single(np => np.Name == "Districts"); capitolCityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "CapitolDistrict", Target = districtType, TargetMultiplicity = EdmMultiplicity.One }); capitolCityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "OutlyingDistricts", Target = districtType, TargetMultiplicity = EdmMultiplicity.Many }); this.citySet = defaultContainer.AddEntitySet("Cities", cityType); this.districtSet = defaultContainer.AddEntitySet("Districts", districtType); this.singletonCity = defaultContainer.AddSingleton("SingletonCity", cityType); // operations var cityReference = new EdmEntityTypeReference(cityType, true); var districtReference = new EdmEntityTypeReference(districtType, true); IEdmPathExpression path = new EdmPathExpression("binding/Districts"); var function = new EdmFunction("TestModel", "GetOneDistrict", districtReference, true, path, true /*isComposable*/); function.AddParameter("binding", cityReference); edmModel.AddElement(function); }
internal static IEdmModel GetEdmModel() { var model = new EdmModel(); // open address var address = new EdmComplexType("NS", "Address", null, false, true); address.AddStructuralProperty("Street", EdmCoreModel.Instance.GetString(true)); address.AddStructuralProperty("City", EdmCoreModel.Instance.GetString(true)); model.AddElement(address); // customer var customer = new EdmEntityType("NS", "Customer"); customer.AddKeys(customer.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false))); customer.AddStructuralProperty("HomeAddress", new EdmComplexTypeReference(address, true)); model.AddElement(customer); // order var order = new EdmEntityType("NS", "Order"); order.AddKeys(order.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false))); model.AddElement(order); var nav = customer.AddBidirectionalNavigation( new EdmNavigationPropertyInfo { Name = "Orders", Target = order, TargetMultiplicity = EdmMultiplicity.Many }, new EdmNavigationPropertyInfo { Name = "Customer", TargetMultiplicity = EdmMultiplicity.ZeroOrOne, }); var container = new EdmEntityContainer("Default", "Container"); model.AddElement(container); var customers = new EdmEntitySet(container, "Customers", customer); container.AddElement(customers); var orders = new EdmEntitySet(container, "Orders", order); container.AddElement(orders); customers.AddNavigationTarget(nav, orders); // bound operations var customerReference = new EdmEntityTypeReference(customer, true); var orderReference = new EdmEntityTypeReference(order, true); IEdmPathExpression path = new EdmPathExpression("binding/Orders"); // entityset path & return type var function = new EdmFunction("NS", "GetSomeOrders", new EdmCollectionTypeReference(new EdmCollectionType(orderReference)), true, path, true /*isComposable*/); function.AddParameter("binding", customerReference); model.AddElement(function); function = new EdmFunction("NS", "GetAnOrder", orderReference, true, path, true /*isComposable*/); function.AddParameter("binding", customerReference); model.AddElement(function); // GetSomeAddressFromCustomer function = new EdmFunction("NS", "GetSomeAddressFromCustomer1", new EdmComplexTypeReference(address, true), true, null, true /*isComposable*/); function.AddParameter("binding", new EdmEntityTypeReference(customer, true)); model.AddElement(function); // We leave the "GetSomeAddressFromCustomer2" code here. // However, the operation with the entity set path containing a complex type doesn't make sense. IEdmPathExpression complexPath = new EdmPathExpression("binding/HomeAddress"); function = new EdmFunction("NS", "GetSomeAddressFromCustomer2", new EdmComplexTypeReference(address, true), true, complexPath, true /*isComposable*/); function.AddParameter("binding", new EdmEntityTypeReference(customer, true)); model.AddElement(function); function = new EdmFunction("NS", "GetSomeAddressFromCustomer3", new EdmComplexTypeReference(address, true), true, null, true /*isComposable*/); function.AddParameter("binding", new EdmEntityTypeReference(customer, true)); model.AddElement(function); var action = new EdmAction("NS", "DoSomeThing", null, true, null); action.AddParameter("binding", new EdmEntityTypeReference(customer, true)); model.AddElement(action); // operation import function = new EdmFunction("NS", "GetSomeOrders2", new EdmCollectionTypeReference(new EdmCollectionType(orderReference))); EdmFunctionImport functionImport = new EdmFunctionImport(container, "GetSomeOrders2", function, new EdmPathExpression("Orders"), false); container.AddElement(functionImport); function = new EdmFunction("NS", "GetAnOrder2", orderReference); functionImport = new EdmFunctionImport(container, "GetAnOrder2", function, new EdmPathExpression("Orders"), false); container.AddElement(functionImport); function = new EdmFunction("NS", "GetSomeAddress", new EdmComplexTypeReference(address, true), false, null, true); functionImport = new EdmFunctionImport(container, "GetSomeAddress", function, null, false); container.AddElement(functionImport); action = new EdmAction("NS", "DoSomeThing2", null, false, null); var actionImport = new EdmActionImport(container, "DoSomeThing2", action, null); container.AddElement(actionImport); return(model); }
private void BuildOperations(EdmModel model, string modelNamespace) { foreach (OperationMethodInfo operationMethodInfo in this.operationInfos) { // With this method, if return type is nullable type,it will get underlying type var returnType = TypeHelper.GetUnderlyingTypeOrSelf(operationMethodInfo.Method.ReturnType); var returnTypeReference = returnType.GetReturnTypeReference(model); bool isBound = operationMethodInfo.IsBound; var bindingParameter = operationMethodInfo.Method.GetParameters().FirstOrDefault(); if (bindingParameter == null && isBound) { // Ignore the method which is marked as bounded but no parameters continue; } string namespaceName = GetNamespaceName(operationMethodInfo, modelNamespace); EdmOperation operation = null; EdmPathExpression path = null; if (isBound) { // Unbound actions or functions should not have EntitySetPath attribute path = BuildEntitySetPathExpression(returnTypeReference, bindingParameter); } if (operationMethodInfo.HasSideEffects) { operation = new EdmAction( namespaceName, operationMethodInfo.Name, returnTypeReference, isBound, path); } else { operation = new EdmFunction( namespaceName, operationMethodInfo.Name, returnTypeReference, isBound, path, operationMethodInfo.IsComposable); } BuildOperationParameters(operation, operationMethodInfo.Method, model); model.AddElement(operation); if (!isBound) { // entitySetReferenceExpression refer to an entity set containing entities returned // by this function/action import. var entitySetReferenceExpression = BuildEntitySetReferenceExpression( model, operationMethodInfo.EntitySet, returnTypeReference); var entityContainer = model.EnsureEntityContainer(this.targetType); if (operationMethodInfo.HasSideEffects) { entityContainer.AddActionImport( operation.Name, (EdmAction)operation, entitySetReferenceExpression); } else { entityContainer.AddFunctionImport( operation.Name, (EdmFunction)operation, entitySetReferenceExpression); } } } }
public static IEdmModel CreateTripPinServiceModel(string ns) { EdmModel model = new EdmModel(); var defaultContainer = new EdmEntityContainer(ns, "DefaultContainer"); model.AddElement(defaultContainer); var genderType = new EdmEnumType(ns, "PersonGender", isFlags: false); genderType.AddMember("Male", new EdmEnumMemberValue(0)); genderType.AddMember("Female", new EdmEnumMemberValue(1)); genderType.AddMember("Unknown", new EdmEnumMemberValue(2)); model.AddElement(genderType); var cityType = new EdmComplexType(ns, "City"); cityType.AddProperty(new EdmStructuralProperty(cityType, "CountryRegion", EdmCoreModel.Instance.GetString(false))); cityType.AddProperty(new EdmStructuralProperty(cityType, "Name", EdmCoreModel.Instance.GetString(false))); cityType.AddProperty(new EdmStructuralProperty(cityType, "Region", EdmCoreModel.Instance.GetString(false))); model.AddElement(cityType); var locationType = new EdmComplexType(ns, "Location", null, false, true); locationType.AddProperty(new EdmStructuralProperty(locationType, "Address", EdmCoreModel.Instance.GetString(false))); locationType.AddProperty(new EdmStructuralProperty(locationType, "City", new EdmComplexTypeReference(cityType, false))); model.AddElement(locationType); var eventLocationType = new EdmComplexType(ns, "EventLocation", locationType, false, true); eventLocationType.AddProperty(new EdmStructuralProperty(eventLocationType, "BuildingInfo", EdmCoreModel.Instance.GetString(true))); model.AddElement(eventLocationType); var airportLocationType = new EdmComplexType(ns, "AirportLocation", locationType, false, true); airportLocationType.AddProperty(new EdmStructuralProperty(airportLocationType, "Loc", EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.GeographyPoint, false))); model.AddElement(airportLocationType); var photoType = new EdmEntityType(ns, "Photo", null, false, false, true); var photoIdProperty = new EdmStructuralProperty(photoType, "Id", EdmCoreModel.Instance.GetInt64(false)); photoType.AddProperty(photoIdProperty); photoType.AddKeys(photoIdProperty); photoType.AddProperty(new EdmStructuralProperty(photoType, "Name", EdmCoreModel.Instance.GetString(true))); model.AddElement(photoType); var photoSet = new EdmEntitySet(defaultContainer, "Photos", photoType); defaultContainer.AddElement(photoSet); var personType = new EdmEntityType(ns, "Person", null, false, /* isOpen */ true); var personIdProperty = new EdmStructuralProperty(personType, "UserName", EdmCoreModel.Instance.GetString(false)); personType.AddProperty(personIdProperty); personType.AddKeys(personIdProperty); personType.AddProperty(new EdmStructuralProperty(personType, "FirstName", EdmCoreModel.Instance.GetString(false))); personType.AddProperty(new EdmStructuralProperty(personType, "LastName", EdmCoreModel.Instance.GetString(false))); personType.AddProperty(new EdmStructuralProperty(personType, "Emails", new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetString(true))))); personType.AddProperty(new EdmStructuralProperty(personType, "AddressInfo", new EdmCollectionTypeReference(new EdmCollectionType(new EdmComplexTypeReference(locationType, true))))); personType.AddProperty(new EdmStructuralProperty(personType, "Gender", new EdmEnumTypeReference(genderType, true))); personType.AddProperty(new EdmStructuralProperty(personType, "Concurrency", EdmCoreModel.Instance.GetInt64(false))); model.AddElement(personType); var personSet = new EdmEntitySet(defaultContainer, "People", personType); defaultContainer.AddElement(personSet); var airlineType = new EdmEntityType(ns, "Airline"); var airlineCodeProp = new EdmStructuralProperty(airlineType, "AirlineCode", EdmCoreModel.Instance.GetString(false)); airlineType.AddKeys(airlineCodeProp); airlineType.AddProperty(airlineCodeProp); airlineType.AddProperty(new EdmStructuralProperty(airlineType, "Name", EdmCoreModel.Instance.GetString(false))); model.AddElement(airlineType); var airlineSet = new EdmEntitySet(defaultContainer, "Airlines", airlineType); defaultContainer.AddElement(airlineSet); var airportType = new EdmEntityType(ns, "Airport"); var airportIdType = new EdmStructuralProperty(airportType, "IcaoCode", EdmCoreModel.Instance.GetString(false)); airportType.AddProperty(airportIdType); airportType.AddKeys(airportIdType); airportType.AddProperty(new EdmStructuralProperty(airportType, "Name", EdmCoreModel.Instance.GetString(false))); airportType.AddProperty(new EdmStructuralProperty(airportType, "IataCode", EdmCoreModel.Instance.GetString(false))); airportType.AddProperty(new EdmStructuralProperty(airportType, "Location", new EdmComplexTypeReference(airportLocationType, false))); model.AddElement(airportType); var airportSet = new EdmEntitySet(defaultContainer, "Airports", airportType); defaultContainer.AddElement(airportSet); var planItemType = new EdmEntityType(ns, "PlanItem"); var planItemIdType = new EdmStructuralProperty(planItemType, "PlanItemId", EdmCoreModel.Instance.GetInt32(false)); planItemType.AddProperty(planItemIdType); planItemType.AddKeys(planItemIdType); planItemType.AddProperty(new EdmStructuralProperty(planItemType, "ConfirmationCode", EdmCoreModel.Instance.GetString(true))); planItemType.AddProperty(new EdmStructuralProperty(planItemType, "StartsAt", EdmCoreModel.Instance.GetDateTimeOffset(true))); planItemType.AddProperty(new EdmStructuralProperty(planItemType, "EndsAt", EdmCoreModel.Instance.GetDateTimeOffset(true))); planItemType.AddProperty(new EdmStructuralProperty(planItemType, "Duration", EdmCoreModel.Instance.GetDuration(true))); model.AddElement(planItemType); var publicTransportationType = new EdmEntityType(ns, "PublicTransportation", planItemType); publicTransportationType.AddProperty(new EdmStructuralProperty(publicTransportationType, "SeatNumber", EdmCoreModel.Instance.GetString(true))); model.AddElement(publicTransportationType); var flightType = new EdmEntityType(ns, "Flight", publicTransportationType); var flightNumberType = new EdmStructuralProperty(flightType, "FlightNumber", EdmCoreModel.Instance.GetString(false)); flightType.AddProperty(flightNumberType); model.AddElement(flightType); var eventType = new EdmEntityType(ns, "Event", planItemType, false, true); eventType.AddProperty(new EdmStructuralProperty(eventType, "Description", EdmCoreModel.Instance.GetString(true))); eventType.AddProperty(new EdmStructuralProperty(eventType, "OccursAt", new EdmComplexTypeReference(eventLocationType, false))); model.AddElement(eventType); var tripType = new EdmEntityType(ns, "Trip"); var tripIdType = new EdmStructuralProperty(tripType, "TripId", EdmCoreModel.Instance.GetInt32(false)); tripType.AddProperty(tripIdType); tripType.AddKeys(tripIdType); tripType.AddProperty(new EdmStructuralProperty(tripType, "ShareId", EdmCoreModel.Instance.GetGuid(true))); tripType.AddProperty(new EdmStructuralProperty(tripType, "Description", EdmCoreModel.Instance.GetString(true))); tripType.AddProperty(new EdmStructuralProperty(tripType, "Name", EdmCoreModel.Instance.GetString(false))); tripType.AddProperty(new EdmStructuralProperty(tripType, "Budget", EdmCoreModel.Instance.GetSingle(false))); tripType.AddProperty(new EdmStructuralProperty(tripType, "StartsAt", EdmCoreModel.Instance.GetDateTimeOffset(false))); tripType.AddProperty(new EdmStructuralProperty(tripType, "EndsAt", EdmCoreModel.Instance.GetDateTimeOffset(false))); tripType.AddProperty(new EdmStructuralProperty(tripType, "Tags", new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetString(false))))); model.AddElement(tripType); var friendsnNavigation = personType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo() { Name = "Friends", Target = personType, TargetMultiplicity = EdmMultiplicity.Many }); var personTripNavigation = personType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo() { Name = "Trips", Target = tripType, TargetMultiplicity = EdmMultiplicity.Many, ContainsTarget = true }); var personPhotoNavigation = personType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo() { Name = "Photo", Target = photoType, TargetMultiplicity = EdmMultiplicity.ZeroOrOne, }); var tripPhotosNavigation = tripType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo() { Name = "Photos", Target = photoType, TargetMultiplicity = EdmMultiplicity.Many, }); var tripItemNavigation = tripType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo() { Name = "PlanItems", Target = planItemType, ContainsTarget = true, TargetMultiplicity = EdmMultiplicity.Many }); var flightFromAirportNavigation = flightType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo() { Name = "From", Target = airportType, TargetMultiplicity = EdmMultiplicity.One }); var flightToAirportNavigation = flightType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo() { Name = "To", Target = airportType, TargetMultiplicity = EdmMultiplicity.One }); var flightAirlineNavigation = flightType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo() { Name = "Airline", Target = airlineType, TargetMultiplicity = EdmMultiplicity.One }); var me = new EdmSingleton(defaultContainer, "Me", personType); defaultContainer.AddElement(me); personSet.AddNavigationTarget(friendsnNavigation, personSet); me.AddNavigationTarget(friendsnNavigation, personSet); var path = new EdmPathExpression("Trips/PlanItems/Microsoft.OData.SampleService.Models.TripPin.Flight/Airline"); personSet.AddNavigationTarget(flightAirlineNavigation, airlineSet, path); me.AddNavigationTarget(flightAirlineNavigation, airlineSet, path); path = new EdmPathExpression("Trips/PlanItems/Microsoft.OData.SampleService.Models.TripPin.Flight/From"); personSet.AddNavigationTarget(flightFromAirportNavigation, airportSet, path); me.AddNavigationTarget(flightFromAirportNavigation, airportSet, path); path = new EdmPathExpression("Trips/PlanItems/Microsoft.OData.SampleService.Models.TripPin.Flight/To"); personSet.AddNavigationTarget(flightToAirportNavigation, airportSet, path); me.AddNavigationTarget(flightToAirportNavigation, airportSet, path); personSet.AddNavigationTarget(personPhotoNavigation, photoSet); me.AddNavigationTarget(personPhotoNavigation, photoSet); path = new EdmPathExpression("Trips/Photos"); personSet.AddNavigationTarget(tripPhotosNavigation, photoSet, path); me.AddNavigationTarget(tripPhotosNavigation, photoSet, path); var getFavoriteAirlineFunction = new EdmFunction(ns, "GetFavoriteAirline", new EdmEntityTypeReference(airlineType, false), true, new EdmPathExpression("person/Trips/PlanItems/Microsoft.OData.SampleService.Models.TripPin.Flight/Airline"), true); getFavoriteAirlineFunction.AddParameter("person", new EdmEntityTypeReference(personType, false)); model.AddElement(getFavoriteAirlineFunction); var getInvolvedPeopleFunction = new EdmFunction(ns, "GetInvolvedPeople", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(personType, false))), true, null, true); getInvolvedPeopleFunction.AddParameter("trip", new EdmEntityTypeReference(tripType, false)); model.AddElement(getInvolvedPeopleFunction); var getFriendsTripsFunction = new EdmFunction(ns, "GetFriendsTrips", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(tripType, false))), true, new EdmPathExpression("person/Friends/Trips"), true); getFriendsTripsFunction.AddParameter("person", new EdmEntityTypeReference(personType, false)); getFriendsTripsFunction.AddParameter("userName", EdmCoreModel.Instance.GetString(false)); model.AddElement(getFriendsTripsFunction); var getNearestAirport = new EdmFunction(ns, "GetNearestAirport", new EdmEntityTypeReference(airportType, false), false, null, true); getNearestAirport.AddParameter("lat", EdmCoreModel.Instance.GetDouble(false)); getNearestAirport.AddParameter("lon", EdmCoreModel.Instance.GetDouble(false)); model.AddElement(getNearestAirport); var getNearestAirportFunctionImport = (IEdmFunctionImport)defaultContainer.AddFunctionImport("GetNearestAirport", getNearestAirport, new EdmPathExpression("Airports"), true); var resetDataSourceAction = new EdmAction(ns, "ResetDataSource", null, false, null); model.AddElement(resetDataSourceAction); defaultContainer.AddActionImport(resetDataSourceAction); var shareTripAction = new EdmAction(ns, "ShareTrip", null, true, null); shareTripAction.AddParameter("person", new EdmEntityTypeReference(personType, false)); shareTripAction.AddParameter("userName", EdmCoreModel.Instance.GetString(false)); shareTripAction.AddParameter("tripId", EdmCoreModel.Instance.GetInt32(false)); model.AddElement(shareTripAction); model.SetDescriptionAnnotation(defaultContainer, "TripPin service is a sample service for OData V4."); model.SetOptimisticConcurrencyAnnotation(personSet, personType.StructuralProperties().Where(p => p.Name == "Concurrency")); // TODO: currently singleton does not support ETag feature // model.SetOptimisticConcurrencyAnnotation(me, personType.StructuralProperties().Where(p => p.Name == "Concurrency")); model.SetResourcePathCoreAnnotation(personSet, "People"); model.SetResourcePathCoreAnnotation(me, "Me"); model.SetResourcePathCoreAnnotation(airlineSet, "Airlines"); model.SetResourcePathCoreAnnotation(airportSet, "Airports"); model.SetResourcePathCoreAnnotation(photoSet, "Photos"); model.SetResourcePathCoreAnnotation(getNearestAirportFunctionImport, "Microsoft.OData.SampleService.Models.TripPin.GetNearestAirport"); model.SetDereferenceableIDsCoreAnnotation(defaultContainer, true); model.SetConventionalIDsCoreAnnotation(defaultContainer, true); model.SetPermissionsCoreAnnotation(personType.FindProperty("UserName"), CorePermission.Read); model.SetPermissionsCoreAnnotation(airlineType.FindProperty("AirlineCode"), CorePermission.Read); model.SetPermissionsCoreAnnotation(airportType.FindProperty("IcaoCode"), CorePermission.Read); model.SetPermissionsCoreAnnotation(planItemType.FindProperty("PlanItemId"), CorePermission.Read); model.SetPermissionsCoreAnnotation(tripType.FindProperty("TripId"), CorePermission.Read); model.SetPermissionsCoreAnnotation(photoType.FindProperty("Id"), CorePermission.Read); model.SetImmutableCoreAnnotation(airportType.FindProperty("IataCode"), true); model.SetComputedCoreAnnotation(personType.FindProperty("Concurrency"), true); model.SetAcceptableMediaTypesCoreAnnotation(photoType, new[] { "image/jpeg" }); model.SetConformanceLevelCapabilitiesAnnotation(defaultContainer, CapabilitiesConformanceLevelType.Advanced); model.SetSupportedFormatsCapabilitiesAnnotation(defaultContainer, new[] { "application/json;odata.metadata=full;IEEE754Compatible=false;odata.streaming=true", "application/json;odata.metadata=minimal;IEEE754Compatible=false;odata.streaming=true", "application/json;odata.metadata=none;IEEE754Compatible=false;odata.streaming=true" }); model.SetAsynchronousRequestsSupportedCapabilitiesAnnotation(defaultContainer, true); model.SetBatchContinueOnErrorSupportedCapabilitiesAnnotation(defaultContainer, false); model.SetNavigationRestrictionsCapabilitiesAnnotation(personSet, CapabilitiesNavigationType.None, new[] { new Tuple <IEdmNavigationProperty, CapabilitiesNavigationType>(friendsnNavigation, CapabilitiesNavigationType.Recursive) }); model.SetFilterFunctionsCapabilitiesAnnotation(defaultContainer, new[] { "contains", "endswith", "startswith", "length", "indexof", "substring", "tolower", "toupper", "trim", "concat", "year", "month", "day", "hour", "minute", "second", "round", "floor", "ceiling", "cast", "isof" }); model.SetSearchRestrictionsCapabilitiesAnnotation(personSet, true, CapabilitiesSearchExpressions.None); model.SetSearchRestrictionsCapabilitiesAnnotation(airlineSet, true, CapabilitiesSearchExpressions.None); model.SetSearchRestrictionsCapabilitiesAnnotation(airportSet, true, CapabilitiesSearchExpressions.None); model.SetSearchRestrictionsCapabilitiesAnnotation(photoSet, true, CapabilitiesSearchExpressions.None); model.SetInsertRestrictionsCapabilitiesAnnotation(personSet, true, new[] { personTripNavigation, friendsnNavigation }); model.SetInsertRestrictionsCapabilitiesAnnotation(airlineSet, true, null); model.SetInsertRestrictionsCapabilitiesAnnotation(airportSet, false, null); model.SetInsertRestrictionsCapabilitiesAnnotation(photoSet, true, null); // TODO: model.SetUpdateRestrictionsCapabilitiesAnnotation(); model.SetDeleteRestrictionsCapabilitiesAnnotation(airportSet, false, null); model.SetISOCurrencyMeasuresAnnotation(tripType.FindProperty("Budget"), "USD"); model.SetScaleMeasuresAnnotation(tripType.FindProperty("Budget"), 2); return(model); }