Ejemplo n.º 1
0
        /// <summary>
        /// Asynchronously produces a base model.
        /// </summary>
        /// <param name="context">
        /// The model context.
        /// </param>
        /// <param name="cancellationToken">
        /// A cancellation token.
        /// </param>
        /// <returns>
        /// A task that represents the asynchronous
        /// operation whose result is the base model.
        /// </returns>
        public Task <IEdmModel> GetModelAsync(
            InvocationContext context,
            CancellationToken cancellationToken)
        {
            Ensure.NotNull(context, "context");

            var    model         = new EdmModel();
            var    dbContext     = context.GetApiService <DbContext>();
            var    elementMap    = new Dictionary <IAnnotatable, IEdmElement>();
            var    entityTypes   = dbContext.Model.GetEntityTypes();
            string namespaceName = CalcNamespace(dbContext, entityTypes);

            var entityContainer = new EdmEntityContainer(
                namespaceName, "Container");
            Dictionary <Type, PropertyInfo> dbSetProperties = GetDbSetPropeties(dbContext);

            // TODO GitHubIssue#36 : support complex and entity inheritance
            foreach (var efEntityType in entityTypes)
            {
                if (elementMap.ContainsKey(efEntityType))
                {
                    continue;
                }

                List <EdmStructuralProperty> concurrencyProperties;
                var entityType = ModelProducer.CreateEntityType(
                    efEntityType, model, out concurrencyProperties);
                model.AddElement(entityType);

                PropertyInfo propInfo;
                if (dbSetProperties.TryGetValue(efEntityType.ClrType, out propInfo))
                {
                    var entitySet = entityContainer.AddEntitySet(propInfo.Name, entityType);
                    if (concurrencyProperties != null)
                    {
                        model.SetOptimisticConcurrencyAnnotation(entitySet, concurrencyProperties);
                    }
                }

                elementMap.Add(efEntityType, entityType);
            }

            CreateNavigations(entityContainer, entityTypes, elementMap);

            // TODO GitHubIssue#36 : support function imports
            model.AddElement(entityContainer);

            return(Task.FromResult <IEdmModel>(model));
        }
Ejemplo n.º 2
0
        private static IEdmModel GetEdmModel()
        {
            EdmModel model = new EdmModel();

            // entity type customer
            EdmEntityType customer = new EdmEntityType("NS", "Customer");
            customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            IEdmStructuralProperty customerName = customer.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            model.AddElement(customer);

            // entity sets
            EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
            model.AddElement(container);
            EdmEntitySet customers = container.AddEntitySet("ETagUntypedCustomers", customer);

            model.SetOptimisticConcurrencyAnnotation(customers, new[] { customerName });

            return model;
        }
        public void AutoComputeETagWithOptimisticConcurrencyAnnotation()
        {
            const string expected = "{" +
                "\"@odata.context\":\"http://example.com/$metadata#People/$entity\"," +
                "\"@odata.id\":\"People(123)\"," +
                "\"@odata.etag\":\"W/\\\"'lucy',12306\\\"\"," +
                "\"@odata.editLink\":\"People(123)\"," +
                "\"@odata.mediaEditLink\":\"People(123)/$value\"," +
                "\"ID\":123," +
                "\"Name\":\"lucy\"," +
                "\"Class\":12306," +
                "\"Alias\":\"lily\"}";
            EdmModel model = new EdmModel();

            EdmEntityType personType = new EdmEntityType("MyNs", "Person", null, false, false, true);
            personType.AddKeys(personType.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            var nameProperty = personType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(isNullable: true));
            var classProperty = personType.AddStructuralProperty("Class", EdmPrimitiveTypeKind.Int32);
            personType.AddStructuralProperty("Alias", EdmCoreModel.Instance.GetString(isNullable: true), null, EdmConcurrencyMode.Fixed);

            var container = new EdmEntityContainer("MyNs", "Container");
            model.AddElement(personType);
            container.AddEntitySet("People", personType);
            model.AddElement(container);

            IEdmEntitySet peopleSet = model.FindDeclaredEntitySet("People");
            model.SetOptimisticConcurrencyAnnotation(peopleSet, new[] { nameProperty, classProperty });
            ODataEntry entry = new ODataEntry
            {
                Properties = new[]
                {
                    new ODataProperty {Name = "ID", Value = 123}, 
                    new ODataProperty {Name = "Name", Value = "lucy"}, 
                    new ODataProperty {Name = "Class", Value = 12306}, 
                    new ODataProperty {Name = "Alias", Value = "lily"},
                }
            };

            string actual = GetWriterOutputForContentTypeAndKnobValue(entry, model, peopleSet, personType);
            Assert.Equal(expected, actual);
        }
Ejemplo n.º 4
0
        public void VerifyAnnotationComputedConcurrency()
        {
            var model = new EdmModel();
            var entity = new EdmEntityType("NS1", "Product");
            var entityId = entity.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));
            entity.AddKeys(entityId);
            EdmStructuralProperty name1 = entity.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));
            EdmStructuralProperty timeVer = entity.AddStructuralProperty("UpdatedTime", EdmCoreModel.Instance.GetDate(false));
            model.AddElement(entity);

            SetComputedAnnotation(model, entityId);  // semantic meaning is V3's 'Identity' for Key profperty
            SetComputedAnnotation(model, timeVer);   // semantic meaning is V3's 'Computed' for non-key profperty

            var entityContainer = new EdmEntityContainer("NS1", "Container");
            model.AddElement(entityContainer);
            EdmEntitySet set1 = new EdmEntitySet(entityContainer, "Products", entity);
            model.SetOptimisticConcurrencyAnnotation(set1, new IEdmStructuralProperty[] { entityId, timeVer });
            entityContainer.AddElement(set1);

            string csdlStr = GetEdmx(model, EdmxTarget.OData);
            Assert.AreEqual(@"<?xml version=""1.0"" encoding=""utf-16""?><edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx""><edmx:DataServices><Schema Namespace=""NS1"" xmlns=""http://docs.oasis-open.org/odata/ns/edm""><EntityType Name=""Product""><Key><PropertyRef Name=""Id"" /></Key><Property Name=""Id"" Type=""Edm.Int32"" Nullable=""false""><Annotation Term=""Org.OData.Core.V1.Computed"" Bool=""true"" /></Property><Property Name=""Name"" Type=""Edm.String"" Nullable=""false"" /><Property Name=""UpdatedTime"" Type=""Edm.Date"" Nullable=""false""><Annotation Term=""Org.OData.Core.V1.Computed"" Bool=""true"" /></Property></EntityType><EntityContainer Name=""Container""><EntitySet Name=""Products"" EntityType=""NS1.Product""><Annotation Term=""Org.OData.Core.V1.OptimisticConcurrency""><Collection><PropertyPath>Id</PropertyPath><PropertyPath>UpdatedTime</PropertyPath></Collection></Annotation></EntitySet></EntityContainer></Schema></edmx:DataServices></edmx:Edmx>", csdlStr);
        }
Ejemplo n.º 5
0
        /// <inheritdoc/>
        public Task<IEdmModel> GetModelAsync(InvocationContext context, CancellationToken cancellationToken)
        {
            Ensure.NotNull(context, "context");
            var model = new EdmModel();
            var apiContext = context.ApiContext;
            var dbContext = apiContext.GetProperty<DbContext>(DbApiConstants.DbContextKey);
            var elementMap = new Dictionary<MetadataItem, IEdmElement>();
            var efModel = (dbContext as IObjectContextAdapter)
                .ObjectContext.MetadataWorkspace;
            var namespaceName = efModel.GetItems<EntityType>(DataSpace.CSpace)
                .Select(t => efModel.GetObjectSpaceType(t).NamespaceName)
                .GroupBy(nameSpace => nameSpace)
                .Select(group => new
                {
                    NameSpace = group.Key,
                    Count = group.Count(),
                })
                .OrderByDescending(nsItem => nsItem.Count)
                .Select(nsItem => nsItem.NameSpace)
                .FirstOrDefault();
            if (namespaceName == null)
            {
                // When dbContext has not a namespace, just use its type name as namespace.
                namespaceName = dbContext.GetType().Namespace ?? dbContext.GetType().Name;
            }

            var efEntityContainer = efModel.GetItems<EntityContainer>(DataSpace.CSpace).Single();
            var entityContainer = new EdmEntityContainer(namespaceName, efEntityContainer.Name);
            elementMap.Add(efEntityContainer, entityContainer);

            // TODO GitHubIssue#36 : support complex and enumeration types
            foreach (var efEntitySet in efEntityContainer.EntitySets)
            {
                var efEntityType = efEntitySet.ElementType;
                if (elementMap.ContainsKey(efEntityType))
                {
                    continue;
                }

                List<EdmStructuralProperty> concurrencyProperties;
                var entityType = CreateEntityType(efModel, efEntityType, model, elementMap, out concurrencyProperties);
                model.AddElement(entityType);
                elementMap.Add(efEntityType, entityType);
                var entitySet = entityContainer.AddEntitySet(efEntitySet.Name, entityType);
                if (concurrencyProperties != null)
                {
                    model.SetOptimisticConcurrencyAnnotation(entitySet, concurrencyProperties);
                }

                elementMap.Add(efEntitySet, entitySet);
            }

            foreach (var efAssociationSet in efEntityContainer.AssociationSets)
            {
                AddNavigationProperties(efAssociationSet, elementMap);
                AddNavigationPropertyBindings(efAssociationSet, elementMap);
            }

            // TODO GitHubIssue#36 : support function imports
            model.AddElement(entityContainer);

            return Task.FromResult<IEdmModel>(model);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Asynchronously produces a base model.
        /// </summary>
        /// <param name="context">
        /// The model context.
        /// </param>
        /// <param name="cancellationToken">
        /// A cancellation token.
        /// </param>
        /// <returns>
        /// A task that represents the asynchronous
        /// operation whose result is the base model.
        /// </returns>
        public Task<IEdmModel> GetModelAsync(
            InvocationContext context,
            CancellationToken cancellationToken)
        {
            var model = new EdmModel();
            var domainContext = context.ApiContext;
            var dbContext = domainContext.GetProperty<DbContext>(DbApiConstants.DbContextKey);
            var elementMap = new Dictionary<IAnnotatable, IEdmElement>();
            var efModel = dbContext.Model;
            var namespaceName = efModel.EntityTypes
                .Select(t => t.HasClrType() ? t.ClrType.Namespace : null)
                .Where(t => t != null)
                .GroupBy(nameSpace => nameSpace)
                .Select(group => new
                {
                    NameSpace = group.Key,
                    Count = group.Count(),
                })
                .OrderByDescending(nsItem => nsItem.Count)
                .Select(nsItem => nsItem.NameSpace)
                .FirstOrDefault();
            if (namespaceName == null)
            {
                // When dbContext has not a namespace, just use its type name as namespace.
                namespaceName = dbContext.GetType().Namespace ?? dbContext.GetType().Name;
            }

            var entityTypes = efModel.EntityTypes;
            var entityContainer = new EdmEntityContainer(
                namespaceName, "Container");

            var dbSetProperties = dbContext.GetType().
                GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).
                Where(e => e.PropertyType.IsGenericType && e.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)).
                ToDictionary(e => e.PropertyType.GetGenericArguments()[0]);

            // TODO GitHubIssue#36 : support complex and entity inheritance
            foreach (var efEntityType in entityTypes)
            {
                if (elementMap.ContainsKey(efEntityType))
                {
                    continue;
                }
                List<EdmStructuralProperty> concurrencyProperties;
                var entityType = ModelProducer.CreateEntityType(
                    efModel, efEntityType, model, out concurrencyProperties);
                model.AddElement(entityType);
                elementMap.Add(efEntityType, entityType);

                System.Reflection.PropertyInfo propInfo;
                if (dbSetProperties.TryGetValue(efEntityType.ClrType, out propInfo))
                {
                    var entitySet = entityContainer.AddEntitySet(propInfo.Name, entityType);
                    if (concurrencyProperties != null)
                    {
                        model.SetOptimisticConcurrencyAnnotation(entitySet, concurrencyProperties);
                    }
                }
            }

            foreach (var efEntityType in entityTypes)
            {
                foreach (var navi in efEntityType.GetNavigations())
                {
                    ModelProducer.AddNavigationProperties(
                        efModel, navi, model, elementMap);
                    ModelProducer.AddNavigationPropertyBindings(
                        efModel, navi, entityContainer, elementMap);
                }
            }

            // TODO GitHubIssue#36 : support function imports
            model.AddElement(entityContainer);

            return Task.FromResult<IEdmModel>(model);
        }
Ejemplo n.º 7
0
        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 EdmIntegerConstant(0));
            genderType.AddMember("Female", new EdmIntegerConstant(1));
            genderType.AddMember("Unknown", new EdmIntegerConstant(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);

            personSet.AddNavigationTarget(flightAirlineNavigation, airlineSet);
            me.AddNavigationTarget(flightAirlineNavigation, airlineSet);

            personSet.AddNavigationTarget(flightFromAirportNavigation, airportSet);
            me.AddNavigationTarget(flightFromAirportNavigation, airportSet);

            personSet.AddNavigationTarget(flightToAirportNavigation, airportSet);
            me.AddNavigationTarget(flightToAirportNavigation, airportSet);

            personSet.AddNavigationTarget(personPhotoNavigation, photoSet);
            me.AddNavigationTarget(personPhotoNavigation, photoSet);

            personSet.AddNavigationTarget(tripPhotosNavigation, photoSet);
            me.AddNavigationTarget(tripPhotosNavigation, photoSet);

            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 EdmEntitySetReferenceExpression(airportSet), 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;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Asynchronously produces a base model.
        /// </summary>
        /// <param name="context">
        /// The model context.
        /// </param>
        /// <param name="cancellationToken">
        /// A cancellation token.
        /// </param>
        /// <returns>
        /// A task that represents the asynchronous
        /// operation whose result is the base model.
        /// </returns>
        public Task <IEdmModel> GetModelAsync(
            InvocationContext context,
            CancellationToken cancellationToken)
        {
            var model         = new EdmModel();
            var domainContext = context.ApiContext;
            var dbContext     = domainContext.GetApiService <DbContext>();
            var elementMap    = new Dictionary <IAnnotatable, IEdmElement>();
            var efModel       = dbContext.Model;
            var namespaceName = efModel.EntityTypes
                                .Select(t => t.HasClrType() ? t.ClrType.Namespace : null)
                                .Where(t => t != null)
                                .GroupBy(nameSpace => nameSpace)
                                .Select(group => new
            {
                NameSpace = group.Key,
                Count     = group.Count(),
            })
                                .OrderByDescending(nsItem => nsItem.Count)
                                .Select(nsItem => nsItem.NameSpace)
                                .FirstOrDefault();

            if (namespaceName == null)
            {
                // When dbContext has not a namespace, just use its type name as namespace.
                namespaceName = dbContext.GetType().Namespace ?? dbContext.GetType().Name;
            }

            var entityTypes     = efModel.EntityTypes;
            var entityContainer = new EdmEntityContainer(
                namespaceName, "Container");

            var dbSetProperties = dbContext.GetType()
                                  .GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
                                  .Where(e => e.PropertyType.IsGenericType &&
                                         e.PropertyType.GetGenericTypeDefinition() == typeof(DbSet <>))
                                  .ToDictionary(e => e.PropertyType.GetGenericArguments()[0]);

            // TODO GitHubIssue#36 : support complex and entity inheritance
            foreach (var efEntityType in entityTypes)
            {
                if (elementMap.ContainsKey(efEntityType))
                {
                    continue;
                }

                List <EdmStructuralProperty> concurrencyProperties;
                var entityType = ModelProducer.CreateEntityType(
                    efModel, efEntityType, model, out concurrencyProperties);
                model.AddElement(entityType);
                elementMap.Add(efEntityType, entityType);

                System.Reflection.PropertyInfo propInfo;
                if (dbSetProperties.TryGetValue(efEntityType.ClrType, out propInfo))
                {
                    var entitySet = entityContainer.AddEntitySet(propInfo.Name, entityType);
                    if (concurrencyProperties != null)
                    {
                        model.SetOptimisticConcurrencyAnnotation(entitySet, concurrencyProperties);
                    }
                }
            }

            foreach (var efEntityType in entityTypes)
            {
                foreach (var navi in efEntityType.GetNavigations())
                {
                    ModelProducer.AddNavigationProperties(
                        efModel, navi, model, elementMap);
                    ModelProducer.AddNavigationPropertyBindings(
                        efModel, navi, entityContainer, elementMap);
                }
            }

            // TODO GitHubIssue#36 : support function imports
            model.AddElement(entityContainer);

            return(Task.FromResult <IEdmModel>(model));
        }
        public CustomersModelWithInheritance()
        {
            EdmModel model = new EdmModel();

            // Enum type simpleEnum
            EdmEnumType simpleEnum = new EdmEnumType("NS", "SimpleEnum");
            simpleEnum.AddMember(new EdmEnumMember(simpleEnum, "First", new EdmIntegerConstant(0)));
            simpleEnum.AddMember(new EdmEnumMember(simpleEnum, "Second", new EdmIntegerConstant(1)));
            simpleEnum.AddMember(new EdmEnumMember(simpleEnum, "Third", new EdmIntegerConstant(2)));
            model.AddElement(simpleEnum);

            // complex type address
            EdmComplexType address = new EdmComplexType("NS", "Address");
            address.AddStructuralProperty("Street", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("State", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("ZipCode", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("Country", EdmPrimitiveTypeKind.String);
            model.AddElement(address);

            // open complex type "Account"
            EdmComplexType account = new EdmComplexType("NS", "Account", null, false, true);
            account.AddStructuralProperty("Bank", EdmPrimitiveTypeKind.String);
            account.AddStructuralProperty("CardNum", EdmPrimitiveTypeKind.Int64);
            model.AddElement(account);

            EdmComplexType specialAccount = new EdmComplexType("NS", "SpecialAccount", account, false, true);
            specialAccount.AddStructuralProperty("SpecialCard", EdmPrimitiveTypeKind.String);
            model.AddElement(specialAccount);

            // entity type customer
            EdmEntityType customer = new EdmEntityType("NS", "Customer");
            customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            IEdmProperty customerName = customer.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            customer.AddStructuralProperty("SimpleEnum", simpleEnum.ToEdmTypeReference(isNullable: false));
            customer.AddStructuralProperty("Address", new EdmComplexTypeReference(address, isNullable: true));
            customer.AddStructuralProperty("Account", new EdmComplexTypeReference(account, isNullable: true));
            IEdmTypeReference primitiveTypeReference = EdmCoreModel.Instance.GetPrimitive(
                EdmPrimitiveTypeKind.String,
                isNullable: true);
            var city = customer.AddStructuralProperty(
                "City",
                primitiveTypeReference,
                defaultValue: null,
                concurrencyMode: EdmConcurrencyMode.Fixed);
            model.AddElement(customer);

            // derived entity type special customer
            EdmEntityType specialCustomer = new EdmEntityType("NS", "SpecialCustomer", customer);
            specialCustomer.AddStructuralProperty("SpecialCustomerProperty", EdmPrimitiveTypeKind.Guid);
            specialCustomer.AddStructuralProperty("SpecialAddress", new EdmComplexTypeReference(address, isNullable: true));
            model.AddElement(specialCustomer);

            // entity type order (open entity type)
            EdmEntityType order = new EdmEntityType("NS", "Order", null, false, true);
            // EdmEntityType order = new EdmEntityType("NS", "Order");
            order.AddKeys(order.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            order.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            order.AddStructuralProperty("Amount", EdmPrimitiveTypeKind.Int32);
            model.AddElement(order);

            // derived entity type special order
            EdmEntityType specialOrder = new EdmEntityType("NS", "SpecialOrder", order, false, true);
            specialOrder.AddStructuralProperty("SpecialOrderProperty", EdmPrimitiveTypeKind.Guid);
            model.AddElement(specialOrder);

            // test entity
            EdmEntityType testEntity = new EdmEntityType("System.Web.OData.Query.Expressions", "TestEntity");
            testEntity.AddStructuralProperty("SampleProperty", EdmPrimitiveTypeKind.Binary);
            model.AddElement(testEntity);

            // containment
            // my order
            EdmEntityType myOrder = new EdmEntityType("NS", "MyOrder");
            myOrder.AddKeys(myOrder.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            myOrder.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            model.AddElement(myOrder);

            // order line
            EdmEntityType orderLine = new EdmEntityType("NS", "OrderLine");
            orderLine.AddKeys(orderLine.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            orderLine.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            model.AddElement(orderLine);

            EdmNavigationProperty orderLinesNavProp = myOrder.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
                {
                    Name = "OrderLines",
                    TargetMultiplicity = EdmMultiplicity.Many,
                    Target = orderLine,
                    ContainsTarget = true,
                });

           EdmNavigationProperty nonContainedOrderLinesNavProp = myOrder.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
                {
                    Name = "NonContainedOrderLines",
                    TargetMultiplicity = EdmMultiplicity.Many,
                    Target = orderLine,
                    ContainsTarget = false,
                });

            EdmAction tag = new EdmAction("NS", "tag", returnType: null, isBound: true, entitySetPathExpression: null);
            tag.AddParameter("entity", new EdmEntityTypeReference(orderLine, false));
            model.AddElement(tag);

            // entity sets
            EdmEntityContainer container = new EdmEntityContainer("NS", "ModelWithInheritance");
            model.AddElement(container);
            EdmEntitySet customers = container.AddEntitySet("Customers", customer);
            EdmEntitySet orders = container.AddEntitySet("Orders", order);
            EdmEntitySet myOrders = container.AddEntitySet("MyOrders", myOrder);

            // singletons
            EdmSingleton vipCustomer = container.AddSingleton("VipCustomer", customer);
            EdmSingleton mary = container.AddSingleton("Mary", customer);
            EdmSingleton rootOrder = container.AddSingleton("RootOrder", order);

            // annotations
            model.SetOptimisticConcurrencyAnnotation(customers, new[] { city });

            // containment
            IEdmContainedEntitySet orderLines = (IEdmContainedEntitySet)myOrders.FindNavigationTarget(orderLinesNavProp);
            
            // no-containment
            IEdmNavigationSource nonContainedOrderLines = myOrders.FindNavigationTarget(nonContainedOrderLinesNavProp);

            // actions
            EdmAction upgrade = new EdmAction("NS", "upgrade", returnType: null, isBound: true, entitySetPathExpression: null);
            upgrade.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(upgrade);

            EdmAction specialUpgrade =
                new EdmAction("NS", "specialUpgrade", returnType: null, isBound: true, entitySetPathExpression: null);
            specialUpgrade.AddParameter("entity", new EdmEntityTypeReference(specialCustomer, false));
            model.AddElement(specialUpgrade);

            // actions bound to collection
            EdmAction upgradeAll = new EdmAction("NS", "UpgradeAll", returnType: null, isBound: true, entitySetPathExpression: null);
            upgradeAll.AddParameter("entityset",
                new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false))));
            model.AddElement(upgradeAll);

            EdmAction upgradeSpecialAll = new EdmAction("NS", "UpgradeSpecialAll", returnType: null, isBound: true, entitySetPathExpression: null);
            upgradeSpecialAll.AddParameter("entityset",
                new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(specialCustomer, false))));
            model.AddElement(upgradeSpecialAll);

            // functions
            IEdmTypeReference returnType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Boolean, isNullable: false);
            IEdmTypeReference stringType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, isNullable: false);
            IEdmTypeReference intType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int32, isNullable: false);

            EdmFunction IsUpgraded = new EdmFunction(
                "NS",
                "IsUpgraded",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            IsUpgraded.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(IsUpgraded);

            EdmFunction orderByCityAndAmount = new EdmFunction(
                "NS",
                "OrderByCityAndAmount",
                stringType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            orderByCityAndAmount.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            orderByCityAndAmount.AddParameter("city", stringType);
            orderByCityAndAmount.AddParameter("amount", intType);
            model.AddElement(orderByCityAndAmount);

            EdmFunction getOrders = new EdmFunction(
                "NS",
                "GetOrders",
                EdmCoreModel.GetCollection(order.ToEdmTypeReference(false)),
                isBound: true,
                entitySetPathExpression: null,
                isComposable: true);
            getOrders.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            getOrders.AddParameter("parameter", intType);
            model.AddElement(getOrders);

            EdmFunction IsSpecialUpgraded = new EdmFunction(
                "NS",
                "IsSpecialUpgraded",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            IsSpecialUpgraded.AddParameter("entity", new EdmEntityTypeReference(specialCustomer, false));
            model.AddElement(IsSpecialUpgraded);

            EdmFunction getSalary = new EdmFunction(
                "NS",
                "GetSalary",
                stringType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            getSalary.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(getSalary);

            getSalary = new EdmFunction(
                "NS",
                "GetSalary",
                stringType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            getSalary.AddParameter("entity", new EdmEntityTypeReference(specialCustomer, false));
            model.AddElement(getSalary);

            EdmFunction IsAnyUpgraded = new EdmFunction(
                "NS",
                "IsAnyUpgraded",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            EdmCollectionType edmCollectionType = new EdmCollectionType(new EdmEntityTypeReference(customer, false));
            IsAnyUpgraded.AddParameter("entityset", new EdmCollectionTypeReference(edmCollectionType));
            model.AddElement(IsAnyUpgraded);

            EdmFunction isCustomerUpgradedWithParam = new EdmFunction(
                "NS",
                "IsUpgradedWithParam",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            isCustomerUpgradedWithParam.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            isCustomerUpgradedWithParam.AddParameter("city", EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, isNullable: false));
            model.AddElement(isCustomerUpgradedWithParam);

            EdmFunction isCustomerLocal = new EdmFunction(
                "NS",
                "IsLocal",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            isCustomerLocal.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(isCustomerLocal);

            EdmFunction entityFunction = new EdmFunction(
                "NS",
                "GetCustomer",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            entityFunction.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            entityFunction.AddParameter("customer", new EdmEntityTypeReference(customer, false));
            model.AddElement(entityFunction);

            EdmFunction getOrder = new EdmFunction(
                "NS",
                "GetOrder",
                order.ToEdmTypeReference(false),
                isBound: true,
                entitySetPathExpression: null,
                isComposable: true); // Composable
            getOrder.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            getOrder.AddParameter("orderId", intType);
            model.AddElement(getOrder);

            // functions bound to collection
            EdmFunction isAllUpgraded = new EdmFunction("NS", "IsAllUpgraded", returnType, isBound: true,
                entitySetPathExpression: null, isComposable: false);
            isAllUpgraded.AddParameter("entityset",
                new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false))));
            isAllUpgraded.AddParameter("param", intType);
            model.AddElement(isAllUpgraded);

            EdmFunction isSpecialAllUpgraded = new EdmFunction("NS", "IsSpecialAllUpgraded", returnType, isBound: true,
                entitySetPathExpression: null, isComposable: false);
            isSpecialAllUpgraded.AddParameter("entityset",
                new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(specialCustomer, false))));
            isSpecialAllUpgraded.AddParameter("param", intType);
            model.AddElement(isSpecialAllUpgraded);

            // navigation properties
            EdmNavigationProperty ordersNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
                {
                    Name = "Orders",
                    TargetMultiplicity = EdmMultiplicity.Many,
                    Target = order
                });
            mary.AddNavigationTarget(ordersNavProp, orders);
            vipCustomer.AddNavigationTarget(ordersNavProp, orders);
            customers.AddNavigationTarget(ordersNavProp, orders);
            orders.AddNavigationTarget(
                 order.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
                 {
                     Name = "Customer",
                     TargetMultiplicity = EdmMultiplicity.ZeroOrOne,
                     Target = customer
                 }),
                customers);

            // navigation properties on derived types.
            EdmNavigationProperty specialOrdersNavProp = specialCustomer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
                {
                    Name = "SpecialOrders",
                    TargetMultiplicity = EdmMultiplicity.Many,
                    Target = order
                });
            vipCustomer.AddNavigationTarget(specialOrdersNavProp, orders);
            customers.AddNavigationTarget(specialOrdersNavProp, orders);
            orders.AddNavigationTarget(
                 specialOrder.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
                 {
                     Name = "SpecialCustomer",
                     TargetMultiplicity = EdmMultiplicity.ZeroOrOne,
                     Target = customer
                 }),
                customers);
            model.SetAnnotationValue<BindableProcedureFinder>(model, new BindableProcedureFinder(model));

            // set properties
            Model = model;
            Container = container;
            Customer = customer;
            Order = order;
            Address = address;
            Account = account;
            SpecialCustomer = specialCustomer;
            SpecialOrder = specialOrder;
            Orders = orders;
            Customers = customers;
            VipCustomer = vipCustomer;
            Mary = mary;
            RootOrder = rootOrder;
            OrderLine = orderLine;
            OrderLines = orderLines; 
            NonContainedOrderLines = nonContainedOrderLines;
            UpgradeCustomer = upgrade;
            UpgradeSpecialCustomer = specialUpgrade;
            CustomerName = customerName;
            IsCustomerUpgraded = isCustomerUpgradedWithParam;
            IsSpecialCustomerUpgraded = IsSpecialUpgraded;
            Tag = tag;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Asynchronously produces a base model.
        /// </summary>
        /// <param name="context">
        /// The model context.
        /// </param>
        /// <param name="cancellationToken">
        /// A cancellation token.
        /// </param>
        /// <returns>
        /// A task that represents the asynchronous
        /// operation whose result is the base model.
        /// </returns>
        public Task <EdmModel> ProduceModelAsync(
            ModelContext context,
            CancellationToken cancellationToken)
        {
            Ensure.NotNull(context);
            var model         = new EdmModel();
            var domainContext = context.DomainContext;
            var dbContext     = domainContext.GetProperty <DbContext>("DbContext");
            var elementMap    = new Dictionary <MetadataItem, IEdmElement>();
            var efModel       = (dbContext as IObjectContextAdapter)
                                .ObjectContext.MetadataWorkspace;
            var namespaceName = efModel.GetItems <EntityType>(DataSpace.CSpace)
                                .Select(t => efModel.GetObjectSpaceType(t).NamespaceName)
                                .GroupBy(nameSpace => nameSpace)
                                .Select(group => new
            {
                NameSpace = group.Key,
                Count     = group.Count(),
            })
                                .OrderByDescending(nsItem => nsItem.Count)
                                .Select(nsItem => nsItem.NameSpace)
                                .FirstOrDefault();

            if (namespaceName == null)
            {
                // When dbContext has not a namespace, just use its type name as namespace.
                namespaceName = dbContext.GetType().Namespace ?? dbContext.GetType().Name;
            }

            var efEntityContainer = efModel.GetItems <EntityContainer>(DataSpace.CSpace).Single();
            var entityContainer   = new EdmEntityContainer(namespaceName, efEntityContainer.Name);

            elementMap.Add(efEntityContainer, entityContainer);

            // TODO GitHubIssue#36 : support complex and enumeration types
            foreach (var efEntitySet in efEntityContainer.EntitySets)
            {
                var efEntityType = efEntitySet.ElementType;
                if (elementMap.ContainsKey(efEntityType))
                {
                    continue;
                }

                List <EdmStructuralProperty> concurrencyProperties;
                var entityType = CreateEntityType(efModel, efEntityType, model, elementMap, out concurrencyProperties);
                model.AddElement(entityType);
                elementMap.Add(efEntityType, entityType);
                var entitySet = entityContainer.AddEntitySet(efEntitySet.Name, entityType);
                if (concurrencyProperties != null)
                {
                    model.SetOptimisticConcurrencyAnnotation(entitySet, concurrencyProperties);
                }

                elementMap.Add(efEntitySet, entitySet);
            }

            foreach (var efAssociationSet in efEntityContainer.AssociationSets)
            {
                AddNavigationProperties(efAssociationSet, elementMap);
                AddNavigationPropertyBindings(efAssociationSet, elementMap);
            }

            // TODO GitHubIssue#36 : support function imports
            model.AddElement(entityContainer);

            return(Task.FromResult(model));
        }
Ejemplo n.º 11
0
        public void TestCoreOptimisticConcurrencyInlineAnnotation()
        {
            EdmModel model = new EdmModel();

            EdmEntityContainer container = new EdmEntityContainer("DefaultNamespace", "Container");
            EdmEntityType personType = new EdmEntityType("DefaultNamespace", "Person");
            EdmStructuralProperty propertyId = personType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));
            personType.AddKeys(propertyId);
            IEdmStructuralProperty concurrencyProperty = personType.AddStructuralProperty("Concurrency", EdmCoreModel.Instance.GetInt32(true));
            model.AddElement(personType);
            container.AddEntitySet("People", personType);
            model.AddElement(container);
            container.AddEntitySet("Students", personType);

            IEdmEntitySet peopleSet = model.FindDeclaredEntitySet("People");
            model.SetOptimisticConcurrencyAnnotation(peopleSet, new[] { concurrencyProperty });
            model.SetOptimisticConcurrencyAnnotation(peopleSet, new[] { concurrencyProperty });

            IEdmEntitySet studentSet = model.FindDeclaredEntitySet("Students");
            model.SetOptimisticConcurrencyAnnotation(studentSet, new[] { concurrencyProperty });

            IEnumerable<EdmError> errors;
            StringWriter sw = new StringWriter();
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = System.Text.Encoding.UTF8;
            XmlWriter xw = XmlWriter.Create(sw, settings);
            model.TryWriteCsdl(xw, out errors);
            xw.Flush();
            xw.Close();
            var actual = sw.ToString();

            const string expected = @"<?xml version=""1.0"" encoding=""utf-16""?>
<Schema Namespace=""DefaultNamespace"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
  <EntityType Name=""Person"">
    <Key>
      <PropertyRef Name=""Id"" />
    </Key>
    <Property Name=""Id"" Type=""Edm.Int32"" Nullable=""false"" />
    <Property Name=""Concurrency"" Type=""Edm.Int32"" />
  </EntityType>
  <EntityContainer Name=""Container"">
    <EntitySet Name=""People"" EntityType=""DefaultNamespace.Person"">
      <Annotation Term=""Org.OData.Core.V1.OptimisticConcurrency"">
        <Collection>
          <PropertyPath>Concurrency</PropertyPath>
        </Collection>
      </Annotation>
    </EntitySet>
    <EntitySet Name=""Students"" EntityType=""DefaultNamespace.Person"">
      <Annotation Term=""Org.OData.Core.V1.OptimisticConcurrency"">
        <Collection>
          <PropertyPath>Concurrency</PropertyPath>
        </Collection>
      </Annotation>
    </EntitySet>
  </EntityContainer>
</Schema>";

            Assert.AreEqual(expected, actual);
        }