public void Apply_TypeNameConventions_Works(string propertyName, EdmMultiplicity multiplicity, bool optional) { // Arrange ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); EntityTypeConfiguration principalEntity = builder.AddEntityType(typeof(DiscoveryPrincipalEntity)); PropertyInfo propertyInfo = typeof(DiscoveryPrincipalEntity).GetProperty(propertyName); principalEntity.HasKey(propertyInfo); EntityTypeConfiguration dependentEntity = builder.AddEntityType(typeof(DiscoveryDependentEntity)); PropertyInfo expectPropertyInfo = typeof(DiscoveryDependentEntity).GetProperty("DiscoveryPrincipalEntity" + propertyName); var property = dependentEntity.AddProperty(expectPropertyInfo); PropertyInfo navigationPropertyInfo = typeof(DiscoveryDependentEntity).GetProperty("Principal"); NavigationPropertyConfiguration navigation = dependentEntity.AddNavigationProperty(navigationPropertyInfo, multiplicity); // Act new ForeignKeyDiscoveryConvention().Apply(navigation, dependentEntity, builder); // Assert PropertyInfo actualPropertyInfo = Assert.Single(navigation.DependentProperties); Assert.Same(expectPropertyInfo, actualPropertyInfo); PropertyInfo principalProperty = Assert.Single(navigation.PrincipalProperties); Assert.Equal(propertyName, principalProperty.Name); Assert.Equal(optional, property.OptionalProperty); }
public void Apply_KeyNameConventions_Works() { // Arrange ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); EntityTypeConfiguration principalEntity = builder.AddEntityType(typeof(DiscoveryPrincipalEntity)); PropertyInfo propertyInfo = typeof(DiscoveryPrincipalEntity).GetProperty("DiscoveryPrincipalEntityId"); principalEntity.HasKey(propertyInfo); EntityTypeConfiguration dependentEntity = builder.AddEntityType(typeof(DiscoveryDependentEntity)); PropertyInfo expectPropertyInfo = typeof(DiscoveryDependentEntity).GetProperty("DiscoveryPrincipalEntityId"); dependentEntity.AddProperty(expectPropertyInfo); PropertyInfo navigationPropertyInfo = typeof(DiscoveryDependentEntity).GetProperty("Principal"); NavigationPropertyConfiguration navigation = dependentEntity.AddNavigationProperty(navigationPropertyInfo, EdmMultiplicity.One); navigation.AddedExplicitly = false; // Act new ForeignKeyDiscoveryConvention().Apply(navigation, dependentEntity, builder); // Assert PropertyInfo actualPropertyInfo = Assert.Single(navigation.DependentProperties); Assert.Same(expectPropertyInfo, actualPropertyInfo); PropertyInfo principalProperty = Assert.Single(navigation.PrincipalProperties); Assert.Equal("DiscoveryPrincipalEntityId", principalProperty.Name); }
public void EntityKeyConvention_DoesnotFigureOutKeyPropertyOnDerivedTypes() { MockType baseType = new MockType("BaseType") .Property <uint>("ID"); MockType derivedType = new MockType("DerivedType") .Property <int>("DerivedTypeID") .BaseType(baseType); ODataConventionModelBuilder builder = ODataConventionModelBuilderFactory.Create(); builder.AddEntityType(derivedType).DerivesFrom(builder.AddEntityType(baseType)); IEdmModel model = builder.GetEdmModel(); IEdmEntityType baseEntity = model.AssertHasEntityType(baseType); baseEntity.AssertHasKey(model, "ID", EdmPrimitiveTypeKind.Int64); IEdmEntityType derivedEntity = model.AssertHasEntityType(derivedType); derivedEntity.AssertHasPrimitiveProperty(model, "DerivedTypeID", EdmPrimitiveTypeKind.Int32, isNullable: false); }
public void ConcurrencyCheckAttributeEdmPropertyConvention_ConfiguresETagPropertyAsETag() { // Arrange MockType type = new MockType("Entity") .Property(typeof(int), "ID") .Property(typeof(int?), "Count", new ConcurrencyCheckAttribute()); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.AddEntityType(type); // Act IEdmModel model = builder.GetEdmModel(); // Assert IEdmEntityType entity = model.AssertHasEntityType(type); IEdmStructuralProperty property = entity.AssertHasPrimitiveProperty( model, "Count", EdmPrimitiveTypeKind.Int32, isNullable: true); Assert.Equal(EdmConcurrencyMode.Fixed, property.ConcurrencyMode); }
/// <summary> /// Initialze a new instance of the <see cref="TableController{TEntity}"/> class. /// </summary> protected TableController() { var modelBuilder = new ODataConventionModelBuilder(); modelBuilder.AddEntityType(typeof(TEntity)); EdmModel = modelBuilder.GetEdmModel(); }
public IEdmModel GetEdmModel() { var builder = new ODataConventionModelBuilder { Namespace = typeof(Customer).Namespace }; // Nicer syntax... // //_modelBuilder // .AddEntitySet<Customer>() // .AddEntitySet<Order>() // ; foreach (var modelType in new [] { typeof(Customer), typeof(Order) }) { var entityType = builder.AddEntityType(modelType); builder.AddEntitySet(string.Format("{0}s", modelType.Name), entityType); } // Add TopBuyer Function to the Customer collection builder .EntityType <Customer>() .Collection .Function("TopBuyer") .ReturnsFromEntitySet <Customer>("Customers"); return(builder.GetEdmModel()); }
public void DataMemberAttributeEdmPropertyConvention_PropertyAliased_IfEnabled(string propertyAlias, bool modelAliasing) { // Arrange MockType relatedType = new MockType("RelatedEntity") .Property <int>("ID"); MockType type = new MockType("Entity") .Property(typeof(int), "ID") .Property(relatedType, "RelatedEntity", new DataMemberAttribute { Name = "AliasRelatedEntity" }); type.Setup(t => t.GetCustomAttributes(It.IsAny <Type>(), It.IsAny <bool>())) .Returns(new[] { new DataContractAttribute() }); // Act ODataConventionModelBuilder builder = ODataConventionModelBuilderHelper.CreateWithModelAliasing(modelAliasing); builder.AddEntityType(type); IEdmModel model = builder.GetEdmModel(); // Assert IEdmEntityType entity = model.AssertHasEntityType(type); entity.AssertHasKey(model, "ID", EdmPrimitiveTypeKind.Int32); entity.AssertHasNavigationProperty( model, propertyAlias, relatedType, isNullable: true, multiplicity: EdmMultiplicity.ZeroOrOne); }
private static IEdmModel GetEdmModel(Type type) { var builder = new ODataConventionModelBuilder(); builder.AddEntitySet(type.Name + "s", builder.AddEntityType(type)); return(builder.GetEdmModel()); }
public void EntityKeyConvention_FiguresOutTheEnumKeyProperty() { // Arrange MockType baseType = new MockType("BaseType") .Property <Color>("ID"); ODataConventionModelBuilder builder = ODataConventionModelBuilderFactory.Create(); builder.AddEntityType(baseType); // Act IEdmModel model = builder.GetEdmModel(); // Assert IEdmEntityType entity = model.AssertHasEntityType(baseType); IEdmStructuralProperty enumProperty = entity.AssertHasProperty <IEdmStructuralProperty>(model, "ID", typeof(Color), false); IEdmProperty enumKey = Assert.Single(entity.DeclaredKey); Assert.Same(enumProperty, enumKey); Assert.Equal(EdmTypeKind.Enum, enumKey.Type.TypeKind()); Assert.Equal("Microsoft.AspNet.OData.Test.Builder.TestModels.Color", enumKey.Type.Definition.FullTypeName()); }
public void Apply_Doesnot_Override_UserConfiguration() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); var vehicles = builder.EntitySet<Vehicle>("vehicles"); var car = builder.AddEntityType(typeof(Car)); var paintAction = vehicles.EntityType.Action("Paint"); paintAction.HasActionLink(ctxt => new Uri("http://localhost/ActionTestWorks"), followsConventions: false); ActionLinkGenerationConvention convention = new ActionLinkGenerationConvention(); convention.Apply(paintAction, builder); IEdmModel model = builder.GetEdmModel(); var vehiclesEdmSet = model.EntityContainer.FindEntitySet("vehicles"); var carEdmType = model.FindDeclaredType("System.Web.OData.Builder.TestModels.Car") as IEdmEntityType; var paintEdmAction = model.GetAvailableProcedures( model.FindDeclaredType("System.Web.OData.Builder.TestModels.Car") as IEdmEntityType).Single() as IEdmAction; Assert.NotNull(paintEdmAction); HttpConfiguration configuration = new HttpConfiguration(); configuration.Routes.MapODataServiceRoute(model); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost"); request.SetConfiguration(configuration); ActionLinkBuilder actionLinkBuilder = model.GetActionLinkBuilder(paintEdmAction); var serializerContext = new ODataSerializerContext { Model = model, NavigationSource = vehiclesEdmSet, Url = request.GetUrlHelper() }; var entityContext = new EntityInstanceContext(serializerContext, carEdmType.AsReference(), new Car { Model = 2009, Name = "Contoso" }); Uri link = actionLinkBuilder.BuildActionLink(entityContext); Assert.Equal("http://localhost/ActionTestWorks", link.AbsoluteUri); }
internal static IEdmModel GetEdmModel(this HttpActionDescriptor actionDescriptor, Type entityClrType) { if (actionDescriptor == null) { throw Error.ArgumentNull("actionDescriptor"); } if (entityClrType == null) { throw Error.ArgumentNull("entityClrType"); } // save the EdmModel to the action descriptor return(actionDescriptor.Properties.GetOrAdd(ModelKeyPrefix + entityClrType.FullName, _ => { IAssembliesResolver resolver = actionDescriptor.Configuration.Services.GetAssembliesResolver(); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(new WebApiAssembliesResolver(resolver), isQueryCompositionMode: true); EntityTypeConfiguration entityTypeConfiguration = builder.AddEntityType(entityClrType); builder.AddEntitySet(entityClrType.Name, entityTypeConfiguration); IEdmModel edmModel = builder.GetEdmModel(); Contract.Assert(edmModel != null); return edmModel; }) as IEdmModel); }
public override IEdmModel GetModel(Type elementClrType, HttpRequestMessage request, HttpActionDescriptor actionDescriptor) { // Get model for the request IEdmModel model = request.ODataProperties().Model; if (model == null) { // user has not configured anything or has registered a model without the element type // let's create one just for this type and cache it in the action descriptor model = actionDescriptor.Properties.GetOrAdd("System.Web.OData.Model+" + elementClrType.FullName, _ => { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(actionDescriptor.Configuration, isQueryCompositionMode: true); builder.EnableLowerCamelCase(); EntityTypeConfiguration entityTypeConfiguration = builder.AddEntityType(elementClrType); builder.AddEntitySet(elementClrType.Name, entityTypeConfiguration); IEdmModel edmModel = builder.GetEdmModel(); Contract.Assert(edmModel != null); return edmModel; }) as IEdmModel; } Contract.Assert(model != null); return model; }
public void Apply_MultiForeignKeysOnForeignKeyProperty_Works() { // Arrange ODataConventionModelBuilder builder = ODataConventionModelBuilderFactory.Create(); builder.EntityType <PrincipalEntity>().HasKey(p => new { p.PrincipalStringId, p.PrincipalIntId }); EntityTypeConfiguration dependentEntity = builder.AddEntityType(typeof(MultiDependentEntity2)); PropertyInfo expectPropertyInfo1 = typeof(MultiDependentEntity2).GetProperty("PrincipalId1"); PrimitivePropertyConfiguration propertyConfig1 = dependentEntity.AddProperty(expectPropertyInfo1); PropertyInfo expectPropertyInfo2 = typeof(MultiDependentEntity2).GetProperty("PrincipalId2"); PrimitivePropertyConfiguration propertyConfig2 = dependentEntity.AddProperty(expectPropertyInfo2); PropertyInfo propertyInfo = typeof(MultiDependentEntity2).GetProperty("Principal"); NavigationPropertyConfiguration navigation = dependentEntity.AddNavigationProperty(propertyInfo, EdmMultiplicity.One); navigation.AddedExplicitly = false; // Act ForeignKeyAttributeConvention convention = new ForeignKeyAttributeConvention(); convention.Apply(propertyConfig1, dependentEntity, builder); convention.Apply(propertyConfig2, dependentEntity, builder); // Assert Assert.Equal(2, navigation.DependentProperties.Count()); Assert.Same(expectPropertyInfo1, navigation.DependentProperties.First()); Assert.Same(expectPropertyInfo2, navigation.DependentProperties.Last()); Assert.Equal(2, navigation.PrincipalProperties.Count()); Assert.Equal("PrincipalIntId", navigation.PrincipalProperties.First().Name); Assert.Equal("PrincipalStringId", navigation.PrincipalProperties.Last().Name); }
public void ConcurrencyCheckAttributeEdmPropertyConvention_DoesnotOverwriteExistingConfiguration() { // Arrange MockType type = new MockType("Entity") .Property(typeof(int), "ID") .Property(typeof(int), "Count", new ConcurrencyCheckAttribute()); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); var entityType = builder.AddEntityType(type); entityType.AddProperty(type.GetProperty("Count")).IsOptional(); builder.AddEntitySet("EntitySet", entityType); // Act IEdmModel model = builder.GetEdmModel(); // Assert IEdmEntityType entity = model.AssertHasEntityType(type); IEdmStructuralProperty property = entity.AssertHasPrimitiveProperty( model, "Count", EdmPrimitiveTypeKind.Int32, isNullable: true); IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("EntitySet"); Assert.NotNull(entitySet); IEnumerable <IEdmStructuralProperty> currencyProperties = model.GetConcurrencyProperties(entitySet); IEdmStructuralProperty currencyProperty = Assert.Single(currencyProperties); Assert.Same(property, currencyProperty); }
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); loggerFactory.AddDebug(); Action <IRouteBuilder> configureRoutes = routeBuilder => { foreach (var Connection in this.Connections) { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(app.ApplicationServices); var entrys = _entrys[Connection.Key]; foreach (Entry entry in entrys) { var entityType = builder.AddEntityType(entry.Type); var entirySet = builder.AddEntitySet(entry.Type.Name, entityType); } var edmModel = builder.GetEdmModel(); routeBuilder.MapODataServiceRoute($"ODATAROUTE_{Connection.Key}", Connection.Key, edmModel); } routeBuilder .Count() .Filter() .OrderBy() .Expand() .Select() .MaxTop(null); routeBuilder.EnableDependencyInjection(); }; app.UseMvc(configureRoutes); app.UseDeveloperExceptionPage(); }
public void Apply_SingleNullableForeignKeyOnNavigationProperty_Works() { // Arrange ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntityType<PrincipalEntity>().HasKey(p => p.PrincipalIntId); EntityTypeConfiguration dependentEntity = builder.AddEntityType(typeof(SingleNullableDependentEntity)); PropertyInfo expectPrincipal = typeof(PrincipalEntity).GetProperty("PrincipalIntId"); PropertyInfo expectDependent = typeof(SingleNullableDependentEntity).GetProperty("PrincipalId"); PrimitivePropertyConfiguration primitiveProperty = dependentEntity.AddProperty(expectDependent); PropertyInfo propertyInfo = typeof(SingleNullableDependentEntity).GetProperty("Principal"); NavigationPropertyConfiguration navigation = dependentEntity.AddNavigationProperty(propertyInfo, EdmMultiplicity.ZeroOrOne); navigation.AddedExplicitly = false; // Act new ForeignKeyAttributeConvention().Apply(navigation, dependentEntity, builder); // Assert PropertyInfo actualPropertyInfo = Assert.Single(navigation.DependentProperties); Assert.Same(expectDependent, actualPropertyInfo); actualPropertyInfo = Assert.Single(navigation.PrincipalProperties); Assert.Same(expectPrincipal, actualPropertyInfo); Assert.True(primitiveProperty.OptionalProperty); }
public void Apply_SingleNullableForeignKeyOnNavigationProperty_Works() { // Arrange ODataConventionModelBuilder builder = ODataConventionModelBuilderFactory.Create(); builder.EntityType <PrincipalEntity>().HasKey(p => p.PrincipalIntId); EntityTypeConfiguration dependentEntity = builder.AddEntityType(typeof(SingleNullableDependentEntity)); PropertyInfo expectPrincipal = typeof(PrincipalEntity).GetProperty("PrincipalIntId"); PropertyInfo expectDependent = typeof(SingleNullableDependentEntity).GetProperty("PrincipalId"); PrimitivePropertyConfiguration primitiveProperty = dependentEntity.AddProperty(expectDependent); PropertyInfo propertyInfo = typeof(SingleNullableDependentEntity).GetProperty("Principal"); NavigationPropertyConfiguration navigation = dependentEntity.AddNavigationProperty(propertyInfo, EdmMultiplicity.ZeroOrOne); navigation.AddedExplicitly = false; // Act new ForeignKeyAttributeConvention().Apply(navigation, dependentEntity, builder); // Assert PropertyInfo actualPropertyInfo = Assert.Single(navigation.DependentProperties); Assert.Same(expectDependent, actualPropertyInfo); actualPropertyInfo = Assert.Single(navigation.PrincipalProperties); Assert.Same(expectPrincipal, actualPropertyInfo); Assert.True(primitiveProperty.OptionalProperty); }
public void DiscoverInheritanceRelationships_PatchesBaseType() { var mockType1 = new MockType("Foo"); var mockType2 = new MockType("Bar").BaseType(mockType1); var mockAssembly = new MockAssembly(mockType1, mockType2); HttpConfiguration configuration = new HttpConfiguration(); configuration.Services.Replace(typeof(IAssembliesResolver), new TestAssemblyResolver(mockAssembly)); var builder = new ODataConventionModelBuilder(configuration); var entity1 = builder.AddEntityType(mockType1); var entity2 = builder.AddEntityType(mockType2); builder.DiscoverInheritanceRelationships(); Assert.Equal(entity1, entity2.BaseType); }
public IODataApiBuilder AddResource(Type type, string customRoute = null) { var route = customRoute ?? type.Name.ToLower(); _metadata.Add(new EntityMetadata(type, route)); var entityType = _modelBuilder.AddEntityType(type); _modelBuilder.AddEntitySet(route, entityType); return(this); }
private static void AddParameter( ODataConventionModelBuilder builder, OperationConfiguration configuration, Type pType, string name) { if (pType.IsPrimitiveType()) { var primitiveType = builder.AddPrimitiveType(pType); configuration.AddParameter(name, primitiveType); } else { if (pType.IsCollection()) { if (pType.GenericTypeArguments[0].GetTypeInfo() .IsPrimitive) { var parameterType = builder.AddPrimitiveType( pType.GenericTypeArguments[0]); var collectionTypeConfig = new CollectionTypeConfiguration( parameterType, pType.GenericTypeArguments[0]); configuration.AddParameter(name, collectionTypeConfig); } else { var parameterType = builder.AddEntityType( pType.GenericTypeArguments[0]); var collectionTypeConfig = new CollectionTypeConfiguration( parameterType, pType.GenericTypeArguments[0]); configuration.AddParameter(name, collectionTypeConfig); } } else { var parameterType = builder.AddEntityType(pType); configuration.AddParameter(name, parameterType); } } }
public static IQueryable ApplyTo <TEntity>(this HttpRequest request, IQueryable <TEntity> query) where TEntity : class { // Parte 1 - Se registran los componentes requeridos por la implementación de // Microsoft ASP.NET Core OData y se memorizan en una variable estática if (_provider == null) { var collection = new ServiceCollection(); collection.AddMvcCore(options => { options.EnableEndpointRouting = false; }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1); collection.AddOData(); collection.AddTransient <ODataUriResolver>(); collection.AddTransient <ODataQueryValidator>(); collection.AddTransient <TopQueryValidator>(); collection.AddTransient <FilterQueryValidator>(); collection.AddTransient <SkipQueryValidator>(); collection.AddTransient <OrderByQueryValidator>(); _provider = collection.BuildServiceProvider(); } // Parte 2 - Se configura la ruta de ASP.NET Core OData if (_routeBuilder == null) { _routeBuilder = new RouteBuilder(new ApplicationBuilder(_provider)); _routeBuilder.EnableDependencyInjection(); } // Parte 3 - Se simula un pedido HTTP como si viniese desde ASP.NET Core var modelBuilder = new ODataConventionModelBuilder(_provider); modelBuilder.AddEntityType(typeof(TEntity)); var edmModel = modelBuilder.GetEdmModel(); var httpContext = new DefaultHttpContext { RequestServices = _provider }; HttpRequest req = new DefaultHttpRequest(httpContext) { Method = "GET", Host = request.Host, Path = request.Path, QueryString = request.QueryString }; var oDataQueryContext = new ODataQueryContext(edmModel, typeof(TEntity), new Microsoft.AspNet.OData.Routing.ODataPath()); var odataQuery = new ODataQueryOptions <TEntity>(oDataQueryContext, req); // Parte 4 - Se aplica la consulta OData al queryable que nos pasan por parámetro return(odataQuery.ApplyTo(query.AsQueryable())); }
/// <summary> /// Registers a product model builder to provide a model for products /// </summary> /// <typeparam name="TBuilder"></typeparam> /// <param name="name">This is the odata endpoint name for this model. You will be able to access this model at /odata/<name></param> /// <param name="builder"></param> /// <returns></returns> public WebApiConfiguration WithProductModel <TBuilder>(string name, TBuilder builder) where TBuilder : IProductModelBuilder { ODataProductsController.Builders.Add(name, builder); EntityTypeConfiguration entity = _odataBuilder.AddEntityType(builder.ModelType); _odataBuilder.AddEntitySet(name, entity); _productModels.Add(name); return(this); }
public static IEdmModel GetEdmModel() { var builder = new ODataConventionModelBuilder(); var customer = builder.EntitySet <Customer>("Customers").EntityType; var type = builder.AddEntityType(typeof(Customer)); IList <PropertyInfo> removedProperties = new List <PropertyInfo>(); foreach (var propertyInfo in typeof(Customer).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) { if (propertyInfo.PropertyType == typeof(DateTime) || propertyInfo.PropertyType == typeof(DateTime?)) // add more codes to process collection { type.RemoveProperty(propertyInfo); removedProperties.Add(propertyInfo); } } // customer.Ignore(c => c.ReleaseDate); EdmModel model = builder.GetEdmModel() as EdmModel; EdmEntityType customerType = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "Customer") as EdmEntityType; var localDateTime = model.FindType("Org.OData.Core.V1.LocalDateTime") as IEdmTypeDefinition; var localDateTimeNullableRef = new EdmTypeDefinitionReference(localDateTime, true); var localDateTimenonNullableRef = new EdmTypeDefinitionReference(localDateTime, false); foreach (var propertyInfo in removedProperties) { EdmProperty edmProperty = null; if (propertyInfo.PropertyType == typeof(DateTime)) { edmProperty = customerType.AddStructuralProperty(propertyInfo.Name, localDateTimenonNullableRef); } else if (propertyInfo.PropertyType == typeof(DateTime?)) { edmProperty = customerType.AddStructuralProperty(propertyInfo.Name, localDateTimeNullableRef); } if (edmProperty != null) { model.SetAnnotationValue(edmProperty, new ClrPropertyInfoAnnotation(propertyInfo)); } } LocalDateTimeConverter converter = new LocalDateTimeConverter(); model.SetPrimitiveValueConverter(localDateTimeNullableRef, converter); model.SetPrimitiveValueConverter(localDateTimenonNullableRef, converter); return(model); }
public static void ClassInitialize(TestContext testContext) { var builder = new ODataConventionModelBuilder(); var type = typeof(MockOpenType); var entityTypeConfiguration = builder.AddEntityType(type); entityTypeConfiguration.HasKey(type.GetProperty("Id")); builder.AddEntitySet(type.Name, entityTypeConfiguration); var edmModels = builder.GetEdmModel(); oDataQueryContext = new ODataQueryContext(edmModels, type, new ODataPath()); }
public static IQueryable ApplyTo <TEntity>(this HttpRequest request, IQueryable <TEntity> query) where TEntity : class { // Part 1 - The components required by the implementation of // Microsoft ASP.NET Core OData and are stored in a static variable if (_provider == null) { var collection = new ServiceCollection(); collection.AddMvc().AddNewtonsoftJson(); collection.AddLogging(); collection.AddOData(); collection.AddTransient <ODataUriResolver>(); collection.AddTransient <ODataQueryValidator>(); collection.AddTransient <TopQueryValidator>(); collection.AddTransient <FilterQueryValidator>(); collection.AddTransient <SkipQueryValidator>(); collection.AddTransient <OrderByQueryValidator>(); _provider = collection.BuildServiceProvider(); } // Part 2 - ASP.NET Core OData path is configured if (_routeBuilder == null) { _routeBuilder = new RouteBuilder(new ApplicationBuilder(_provider)); _routeBuilder.EnableDependencyInjection(); } // Part 3 - An HTTP request is simulated as if it came from ASP.NET Core var modelBuilder = new ODataConventionModelBuilder(_provider); modelBuilder.AddEntityType(typeof(TEntity)); var edmModel = modelBuilder.GetEdmModel(); var httpContext = request.HttpContext; httpContext.RequestServices = _provider; HttpRequest req = request; req.Method = "GET"; req.Host = request.Host; req.Path = request.Path; req.QueryString = request.QueryString; req.HttpContext.RequestServices = _provider; var oDataQueryContext = new ODataQueryContext(edmModel, typeof(TEntity), new Microsoft.AspNet.OData.Routing.ODataPath()); var odataQuery = new ODataQueryOptions <TEntity>(oDataQueryContext, req); // Part 4 - The OData query is applied to the queryable that is passed to us by parameter return(odataQuery.ApplyTo(query.AsQueryable())); }
public void EntityKeyConvention_DoesnotFigureOutKeyPropertyOnDerivedTypes() { MockType baseType = new MockType("BaseType") .Property<uint>("ID"); MockType derivedType = new MockType("DerivedType") .Property<int>("DerivedTypeID") .BaseType(baseType); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.AddEntityType(derivedType).DerivesFrom(builder.AddEntityType(baseType)); IEdmModel model = builder.GetEdmModel(); IEdmEntityType baseEntity = model.AssertHasEntityType(baseType); baseEntity.AssertHasKey(model, "ID", EdmPrimitiveTypeKind.Int64); IEdmEntityType derivedEntity = model.AssertHasEntityType(derivedType); derivedEntity.AssertHasPrimitiveProperty(model, "DerivedTypeID", EdmPrimitiveTypeKind.Int32, isNullable: false); }
/// <summary> /// Add given all given <see cref="Type"/> objects with a Id Property to the <see cref="ODataConventionModelBuilder"/> list of <see cref="EntitySetConfiguration"/> /// </summary> /// <param name="odataModelBuilder">the <see cref="ODataConventionModelBuilder"/> instance used to build the odata conventions</param> /// <param name="types">the given types to be mapped and added to the <see cref="EntitySetConfiguration"/> collection</param> /// <returns>the given instance of <see cref="ODataConventionModelBuilder"/> with a <see cref="EntitySetConfiguration"/> item for each <see cref="Type"/> given</returns> public static ODataConventionModelBuilder AddTypesToOdataEntitySet(this ODataConventionModelBuilder odataModelBuilder, params Type[] types) { foreach (var type in types) { if (!type.GetProperties().Any(d => d.Name == "Id")) { continue; } odataModelBuilder.AddEntitySet(type.Name, odataModelBuilder.AddEntityType(type)); } odataModelBuilder.ModelAliasingEnabled = true; return(odataModelBuilder); }
public void EntityKeyConvention_FiguresOutTheKeyProperty() { MockType baseType = new MockType("BaseType") .Property<uint>("ID"); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.AddEntityType(baseType); IEdmModel model = builder.GetEdmModel(); IEdmEntityType entity = model.AssertHasEntityType(baseType); entity.AssertHasKey(model, "ID", EdmPrimitiveTypeKind.Int64); }
private IEdmModel GetEdmModel() { var builder = new ODataConventionModelBuilder(); var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IGenericODataModel))).ToList(); foreach (Type type in types) { var entityTypeConfig = builder.AddEntityType(type); builder.AddEntitySet(type.Name, entityTypeConfig); } return(builder.GetEdmModel()); }
// borrowed from WebApi/src/Microsoft.AspNet.OData/Extensions/HttpActionDescriptorExtensions.cs internal static IEdmModel GetEdmModel(HttpActionDescriptor actionDescriptor, Type entityClrType) { // save the EdmModel to the action descriptor return(actionDescriptor.Properties.GetOrAdd(ModelKeyPrefix + entityClrType.FullName, _ => { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(actionDescriptor.Configuration, isQueryCompositionMode: true); EntityTypeConfiguration entityTypeConfiguration = builder.AddEntityType(entityClrType); builder.AddEntitySet(entityClrType.Name, entityTypeConfiguration); IEdmModel edmModel = builder.GetEdmModel(); Contract.Assert(edmModel != null); return edmModel; }) as IEdmModel); }
public void RequiredAttributeEdmPropertyConvention_ConfiguresRequiredPropertyAsRequired() { MockType type = new MockType("Entity") .Property(typeof(int), "ID") .Property(typeof(int?), "Count", new RequiredAttribute()); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.AddEntityType(type); IEdmModel model = builder.GetEdmModel(); IEdmEntityType entity = model.AssertHasEntityType(type); entity.AssertHasPrimitiveProperty(model, "Count", EdmPrimitiveTypeKind.Int32, isNullable: false); }
public void RequiredAttributeEdmPropertyConvention_DoesnotOverwriteExistingConfiguration() { MockType type = new MockType("Entity") .Property(typeof(int), "ID") .Property(typeof(int), "Count", new RequiredAttribute()); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.AddEntityType(type).AddProperty(type.GetProperty("Count")).IsOptional(); IEdmModel model = builder.GetEdmModel(); IEdmEntityType entity = model.AssertHasEntityType(type); entity.AssertHasPrimitiveProperty(model, "Count", EdmPrimitiveTypeKind.Int32, isNullable: true); }
public static IEdmModel GetEdmModel(IServiceProvider servicePrivider) { var builder = new ODataConventionModelBuilder(servicePrivider); var entitySets = typeof(AppDbContext).GetProperties().Where(x => x.MemberType == System.Reflection.MemberTypes.Property && x.PropertyType.IsGenericType && x.PropertyType.GetGenericTypeDefinition() == typeof(DbSet <>)).ToList(); foreach (var entitySet in entitySets) { Type type = entitySet.PropertyType.GenericTypeArguments.First(); EntityTypeConfiguration entityTypeConfiguration = builder.AddEntityType(type); builder.AddEntitySet(entitySet.Name, entityTypeConfiguration); } return(builder.GetEdmModel()); }
public void Apply_DoesnotRemove_ExplicitlyAddedProperties() { // Arrange ODataConventionModelBuilder builder = new ODataConventionModelBuilder() { ModelAliasingEnabled = false }; PropertyInfo propertyInfo = typeof(TestEntity).GetProperty("ExplicitlyAddedProperty"); EntityTypeConfiguration entity = builder.AddEntityType(typeof(TestEntity)); PropertyConfiguration property = entity.AddProperty(propertyInfo); // Act _convention.Apply(entity, builder); // Assert Assert.Contains(propertyInfo, entity.ExplicitProperties.Keys); Assert.DoesNotContain(propertyInfo, entity.RemovedProperties); }
public void Apply_DoesnotModifiy_ExplicitlyAddedAction() { // Arrange ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); PropertyInfo propertyInfo = typeof(TestOrder).GetProperty("Customer"); EntityTypeConfiguration entity = builder.AddEntityType(typeof(TestOrder)); NavigationPropertyConfiguration navProperty = entity.AddNavigationProperty(propertyInfo, EdmMultiplicity.One); navProperty.OnDeleteAction = EdmOnDeleteAction.None; // Act new ActionOnDeleteAttributeConvention().Apply(navProperty, entity, builder); // Assert Assert.Equal(EdmOnDeleteAction.None, navProperty.OnDeleteAction); }
public static IEdmModel BuildEdmModel(Type ApiContextType) { ODataModelBuilder builder = new ODataConventionModelBuilder(); builder.Namespace = ApiContextType.Namespace; var publicProperties = ApiContextType.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var property in publicProperties) { var entityClrType = TypeHelper.GetImplementedIEnumerableType(property.PropertyType); EntityTypeConfiguration entity = builder.AddEntityType(entityClrType); builder.AddEntitySet(property.Name, entity); } return builder.GetEdmModel(); }
public static IEdmModel GetEdmModel() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); var types = typeof(EntityBase).Assembly.GetTypes(); foreach (var type in types) { if (type.BaseType == typeof(EntityBase) && type.GetCustomAttribute <AutoGeneratedOdataControllerAttribute>() is AutoGeneratedOdataControllerAttribute) { builder.AddEntitySet(type.Name, builder.AddEntityType(type)); } } return(builder.GetEdmModel()); }
public void Apply_DoesnotRemove_ExplicitlyAddedProperties() { // Arrange ODataConventionModelBuilder builder = ODataConventionModelBuilderHelper.CreateWithModelAliasing(modelAliasing: false); PropertyInfo propertyInfo = typeof(TestEntity).GetProperty("ExplicitlyAddedProperty"); EntityTypeConfiguration entity = builder.AddEntityType(typeof(TestEntity)); PropertyConfiguration property = entity.AddProperty(propertyInfo); // Act _convention.Apply(entity, builder); // Assert Assert.Contains(propertyInfo, entity.ExplicitProperties.Keys); Assert.DoesNotContain(propertyInfo, entity.RemovedProperties); }
public void Apply_DoesnotRemove_ExplicitlyAddedProperties() { // Arrange ODataConventionModelBuilder builder = ODataConventionModelBuilderFactory.Create(); PropertyInfo propertyInfo = typeof(TestEntity).GetProperty("ExplicitlyAddedProperty"); EntityTypeConfiguration entity = builder.AddEntityType(typeof(TestEntity)); PropertyConfiguration property = entity.AddProperty(propertyInfo); // Act new IgnoreDataMemberAttributeEdmPropertyConvention().Apply(property, entity, builder); // Assert Assert.Contains(propertyInfo, entity.ExplicitProperties.Keys); Assert.DoesNotContain(propertyInfo, entity.RemovedProperties); }
public static void ClassInitialize(TestContext testContext) { var builder = new ODataConventionModelBuilder(); var type = typeof(MockOpenType); var entityTypeConfiguration = builder.AddEntityType(type); entityTypeConfiguration.HasKey(type.GetProperty("Id")); builder.AddEntitySet(type.Name, entityTypeConfiguration); var conf = builder.EntitySet <MockOpenType>(type.Name); conf.EntityType.Property(p => p.Id).Name = "id"; var edmModels = builder.GetEdmModel(); ODataQueryContext = new ODataQueryContext(edmModels, type, new ODataPath()); var collection = new ServiceCollection(); #if NET6_0 collection .AddControllers() .AddOData(); #else collection.AddOData(); #endif collection.AddODataQueryFilter(); collection.AddTransient <ODataUriResolver>(); collection.AddTransient <ODataQueryValidator>(); collection.AddTransient <TopQueryValidator>(); collection.AddTransient <FilterQueryValidator>(); collection.AddTransient <SkipQueryValidator>(); collection.AddTransient <OrderByQueryValidator>(); #if NET6_0 collection.AddTransient <ILoggerFactory, TestLoggingFactory>(); #endif Provider = collection.BuildServiceProvider(); var applicationBuilder = Substitute.For <IApplicationBuilder>(); applicationBuilder.ApplicationServices.Returns(Provider); #if !NET6_0 var routeBuilder = new RouteBuilder(applicationBuilder); routeBuilder.EnableDependencyInjection(); #endif }
private static IEdmModel CreateImplicitModel(HttpConfiguration configuration, Type elementClrType) { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(configuration, isQueryCompositionMode: true); // Add the type to the model as an entity and add an entity set with the same name. EntityTypeConfiguration entityTypeConfiguration = builder.AddEntityType(elementClrType); builder.AddEntitySet(elementClrType.Name, entityTypeConfiguration); // Build the model and add the AuthorizedRolesAnnotation. IEdmModel edmModel = builder.GetEdmModel(); Contract.Assert(edmModel != null); edmModel.AddAuthorizedRolesAnnotations(); return edmModel; }
public void Apply_DoesnotRemove_ExplicitlyAddedProperties() { // Arrange ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); PropertyInfo propertyInfo = typeof(TestEntity).GetProperty("Property"); EntityTypeConfiguration entity = builder.AddEntityType(typeof(TestEntity)); PropertyConfiguration property = entity.AddProperty(propertyInfo); // Act new NotMappedAttributeConvention().Apply(property, entity, builder); // Assert Assert.Contains(propertyInfo, entity.ExplicitProperties.Keys); Assert.DoesNotContain(propertyInfo, entity.RemovedProperties); }
public static IEdmModel BuildEdmModel(Type apiContextType, AssembliesResolver assembliesResolver, Action<ODataConventionModelBuilder> after = null) { var builder = new ODataConventionModelBuilder(assembliesResolver) { Namespace = apiContextType.Namespace }; var publicProperties = apiContextType.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var property in publicProperties) { var entityClrType = TypeHelper.GetImplementedIEnumerableType(property.PropertyType); var entity = builder.AddEntityType(entityClrType); builder.AddEntitySet(property.Name, entity); } after?.Invoke(builder); var edmModel = builder.GetEdmModel(); return edmModel; }
public void RequiredAttributeEdmPropertyConvention_ConfiguresRequiredNavigationPropertyAsRequired() { MockType anotherType = new MockType("RelatedEntity") .Property<int>("ID"); MockType type = new MockType("Entity") .Property(typeof(int), "ID") .Property(anotherType, "RelatedEntity", new RequiredAttribute()); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.AddEntityType(type); IEdmModel model = builder.GetEdmModel(); IEdmEntityType entity = model.AssertHasEntityType(type); entity.AssertHasNavigationProperty(model, "RelatedEntity", anotherType, isNullable: false, multiplicity: EdmMultiplicity.One); }
public void Apply_ActionOnDeleteAttribute_Works() { // Arrange Type orderType = typeof(TestOrder); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); PropertyInfo propertyInfo = orderType.GetProperty("Customer"); EntityTypeConfiguration entity = builder.AddEntityType(orderType); NavigationPropertyConfiguration navProperty = entity.AddNavigationProperty(propertyInfo, EdmMultiplicity.One); navProperty.AddedExplicitly = false; navProperty.HasConstraint(orderType.GetProperty("CustomerId"), typeof(TestCustomer).GetProperty("Id")); // Act new ActionOnDeleteAttributeConvention().Apply(navProperty, entity, builder); // Assert Assert.Equal(EdmOnDeleteAction.Cascade, navProperty.OnDeleteAction); }
public void ConcurrencyCheckAttributeEdmPropertyConvention_DoesnotOverwriteExistingConfiguration() { MockType type = new MockType("Entity") .Property(typeof(int), "ID") .Property(typeof(int), "Count", new ConcurrencyCheckAttribute()); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.AddEntityType(type).AddProperty(type.GetProperty("Count")).IsOptional(); IEdmModel model = builder.GetEdmModel(); IEdmEntityType entity = model.AssertHasEntityType(type); IEdmStructuralProperty property = entity.AssertHasPrimitiveProperty( model, "Count", EdmPrimitiveTypeKind.Int32, isNullable: true); Assert.Equal(EdmConcurrencyMode.Fixed, property.ConcurrencyMode); }
private static ODataConventionModelBuilder MapAllODataModels(string namespaceForTypes) { var builder = new ODataConventionModelBuilder(); var types = Assembly.GetExecutingAssembly() .GetTypes() .Where(x => string.Equals(x.Namespace, namespaceForTypes, StringComparison.Ordinal)); foreach (var type in types) { var name = type.GetCustomAttribute(typeof (ApiMapNameAttribute)) as ApiMapNameAttribute; if (name == null) continue; var entityType = builder.AddEntityType(type); builder.AddEntitySet(name.Name, entityType); } return builder; }
internal static IEdmModel GetEdmModel(this HttpActionDescriptor actionDescriptor, Type entityClrType) { if (actionDescriptor == null) { throw Error.ArgumentNull("actionDescriptor"); } if (entityClrType == null) { throw Error.ArgumentNull("entityClrType"); } // save the EdmModel to the action descriptor return actionDescriptor.Properties.GetOrAdd(ModelKeyPrefix + entityClrType.FullName, _ => { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(actionDescriptor.Configuration, isQueryCompositionMode: true); EntityTypeConfiguration entityTypeConfiguration = builder.AddEntityType(entityClrType); builder.AddEntitySet(entityClrType.Name, entityTypeConfiguration); IEdmModel edmModel = builder.GetEdmModel(); Contract.Assert(edmModel != null); return edmModel; }) as IEdmModel; }
public void EntityKeyConvention_FiguresOutTheEnumKeyProperty() { // Arrange MockType baseType = new MockType("BaseType") .Property<Color>("ID"); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.AddEntityType(baseType); // Act IEdmModel model = builder.GetEdmModel(); // Assert IEdmEntityType entity = model.AssertHasEntityType(baseType); IEdmStructuralProperty enumProperty = entity.AssertHasProperty<IEdmStructuralProperty>(model, "ID", typeof(Color), false); IEdmProperty enumKey = Assert.Single(entity.DeclaredKey); Assert.Same(enumProperty, enumKey); Assert.Equal(EdmTypeKind.Enum, enumKey.Type.TypeKind()); Assert.Equal("System.Web.OData.Builder.TestModels.Color", enumKey.Type.Definition.FullTypeName()); }
public void ModelBuilder_ProductsWithFilterSortableExplicitly() { var modelBuilder = new ODataConventionModelBuilder(); var entityTypeConf = modelBuilder.AddEntityType(typeof(ProductWithFilterSortable)); entityTypeConf.AddProperty(typeof(ProductWithFilterSortable).GetProperty("NonFilterableProperty")); entityTypeConf.AddProperty(typeof(ProductWithFilterSortable).GetProperty("UnsortableProperty")); entityTypeConf.AddNavigationProperty(typeof(ProductWithFilterSortable).GetProperty("Category"), EdmMultiplicity.One); var model = modelBuilder.GetEdmModel(); var prop = entityTypeConf.Properties.FirstOrDefault(p => p.Name == "NonFilterableProperty"); Assert.False(prop.NonFilterable); prop = entityTypeConf.Properties.FirstOrDefault(p => p.Name == "UnsortableProperty"); Assert.False(prop.Unsortable); prop = entityTypeConf.Properties.FirstOrDefault(p => p.Name == "Category"); Assert.False(prop.NotNavigable); Assert.False(prop.NotExpandable); }
public void ModelBuilder_SupportsPrimitiveCollection(Type primitiveCollectionPropertyType) { var modelBuilder = new ODataConventionModelBuilder(); Type entityType = new MockType("SampleType") .Property<int>("ID") .Property(primitiveCollectionPropertyType, "Property1"); modelBuilder.AddEntityType(entityType); IEdmModel model = modelBuilder.GetEdmModel(); IEdmEntityType entity = model.GetEdmType(entityType) as IEdmEntityType; Assert.NotNull(entity); Assert.Equal(2, entity.DeclaredProperties.Count()); IEdmStructuralProperty property1 = entity.DeclaredProperties.OfType<IEdmStructuralProperty>().SingleOrDefault(p => p.Name == "Property1"); Assert.NotNull(property1); Assert.Equal(EdmTypeKind.Collection, property1.Type.Definition.TypeKind); Assert.Equal(EdmTypeKind.Primitive, (property1.Type.Definition as IEdmCollectionType).ElementType.Definition.TypeKind); }
public void ModelBuilder_DoesnotThrow_ForEntityCollection(Type collectionType) { var modelBuilder = new ODataConventionModelBuilder(); Type entityType = new MockType("SampleType") .Property<int>("ID") .Property(collectionType, "Products"); modelBuilder.AddEntityType(entityType); Assert.DoesNotThrow( () => modelBuilder.GetEdmModel()); }
public void DerivedTypes_Can_DefineKeys_InQueryCompositionMode() { // Arrange MockType baseType = new MockType("BaseType") .Property(typeof(int), "ID"); MockType derivedType = new MockType("DerivedType") .Property(typeof(int), "DerivedTypeId") .BaseType(baseType); MockAssembly assembly = new MockAssembly(baseType, derivedType); HttpConfiguration configuration = new HttpConfiguration(); configuration.Services.Replace(typeof(IAssembliesResolver), new TestAssemblyResolver(assembly)); var builder = new ODataConventionModelBuilder(configuration, isQueryCompositionMode: true); builder.AddEntitySet("bases", builder.AddEntityType(baseType)); // Act IEdmModel model = builder.GetEdmModel(); // Assert model.AssertHasEntitySet("bases", baseType); IEdmEntityType baseEntityType = model.AssertHasEntityType(baseType); IEdmEntityType derivedEntityType = model.AssertHasEntityType(derivedType, baseType); baseEntityType.AssertHasKey(model, "ID", EdmPrimitiveTypeKind.Int32); derivedEntityType.AssertHasPrimitiveProperty(model, "DerivedTypeId", EdmPrimitiveTypeKind.Int32, isNullable: false); }
public void ModelBuilder_DerivedComplexTypeHavingKeys_Throws() { MockType baseComplexType = new MockType("BaseComplexType"); MockType derivedComplexType = new MockType("DerivedComplexType") .Property(typeof(int), "DerivedComplexTypeId") .BaseType(baseComplexType); MockType entityType = new MockType("EntityType") .Property(typeof(int), "ID") .Property(baseComplexType.Object, "ComplexProperty"); MockAssembly assembly = new MockAssembly(baseComplexType, derivedComplexType, entityType); HttpConfiguration configuration = new HttpConfiguration(); configuration.Services.Replace(typeof(IAssembliesResolver), new TestAssemblyResolver(assembly)); var builder = new ODataConventionModelBuilder(configuration); builder.AddEntitySet("entities", builder.AddEntityType(entityType)); Assert.Throws<InvalidOperationException>( () => builder.GetEdmModel(), "Cannot define keys on type 'DefaultNamespace.DerivedComplexType' deriving from 'DefaultNamespace.BaseComplexType'. Only the root type in the entity inheritance hierarchy can contain keys."); }
public void RequiredAttributeEdmPropertyConvention_DoesnotOverwriteExistingConfigurationForNavigationProperties() { MockType anotherType = new MockType("RelatedEntity") .Property<int>("ID"); MockType type = new MockType("Entity") .Property(typeof(int), "ID") .Property(anotherType, "RelatedEntity", new RequiredAttribute()); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.AddEntityType(type).AddNavigationProperty(type.GetProperty("RelatedEntity"), EdmMultiplicity.ZeroOrOne); IEdmModel model = builder.GetEdmModel(); IEdmEntityType entity = model.AssertHasEntityType(type); entity.AssertHasNavigationProperty(model, "RelatedEntity", anotherType, isNullable: true, multiplicity: EdmMultiplicity.ZeroOrOne); }
public void ModelBuilder_DerivedComplexTypeHavingKeys_SuccedsIfToldToBeComplex() { MockType baseComplexType = new MockType("BaseComplexType"); MockType derivedComplexType = new MockType("DerivedComplexType") .Property(typeof(int), "DerivedComplexTypeId") .BaseType(baseComplexType); MockType entityType = new MockType("EntityType") .Property(typeof(int), "ID") .Property(baseComplexType.Object, "ComplexProperty"); MockAssembly assembly = new MockAssembly(baseComplexType, derivedComplexType, entityType); HttpConfiguration configuration = new HttpConfiguration(); configuration.Services.Replace(typeof(IAssembliesResolver), new TestAssemblyResolver(assembly)); var builder = new ODataConventionModelBuilder(configuration); builder.AddEntitySet("entities", builder.AddEntityType(entityType)); builder.AddComplexType(baseComplexType); IEdmModel model = builder.GetEdmModel(); Assert.Equal(3, model.SchemaElements.Count()); Assert.NotNull(model.FindType("DefaultNamespace.EntityType")); Assert.NotNull(model.FindType("DefaultNamespace.BaseComplexType")); }