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