Beispiel #1
0
        internal Uri GenerateLocationHeader()
        {
            Contract.Assert(_controller.ContainerMetadata != null);

            Type clrType  = Entity.GetType();
            Type baseType = clrType.BaseType;
            IEntitySetMetadata entitySetMetadata = _controller.ContainerMetadata.GetEntitySetFor(clrType);

            while (entitySetMetadata == null && baseType != null)
            {
                entitySetMetadata = _controller.ContainerMetadata.GetEntitySetFor(baseType);
                baseType          = baseType.BaseType;
            }

            if (entitySetMetadata == null)
            {
                throw new InvalidOperationException("IEntitySetMetadata not found for entity type " + clrType.FullName);
            }

            IEntityTypeMetadata entityTypeMetadata = _controller.ContainerMetadata.GetEntityType(clrType);

            if (entityTypeMetadata == null)
            {
                throw new InvalidOperationException("IEntityTypeMetadata not found for entity type " + clrType.FullName);
            }

            object keyValue  = entityTypeMetadata.SingleClrKeyProperty.GetValue(Entity);
            string keyString = ODataUriUtils.ConvertToUriLiteral(keyValue, ODataVersion.V3, Request.ODataProperties().Model);

            string oDataLink = _controller.Url.CreateODataLink(new EntitySetPathSegment(entitySetMetadata.Name), new KeyValuePathSegment(keyString));

            return(new Uri(oDataLink));
        }
		public static IEntitySetMetadata GetEntitySetFor(this IContainerMetadata containerMetadata, IEntityTypeMetadata entityTypeMetadata)
		{
			Contract.Requires<ArgumentNullException>(containerMetadata != null);
			Contract.Requires<ArgumentNullException>(entityTypeMetadata != null);

			return containerMetadata.EntitySets.SingleOrDefault(es => es.ElementTypeMetadata.ClrType == entityTypeMetadata.ClrType);
		}
Beispiel #3
0
        public static object GetKeyFor <TEntity>(this IContainerMetadata containerMetadata, TEntity entity)
        {
            Contract.Requires <ArgumentNullException>(containerMetadata != null);
            Contract.Requires <ArgumentNullException>(entity != null);

            IEntityTypeMetadata entityTypeMetadata = containerMetadata.GetEntityType(typeof(TEntity));

            return(entityTypeMetadata.EntityKeyFunction(entity));
        }
        private static void AddTypeToDbContext(IEntityTypeMetadata type, CodeTypeDeclaration codeDbContext)
        {
            var snippet = new CodeSnippetTypeMember
            {
                Text = $"		public virtual DbSet<{type.Name}> {type.TableName ?? type.Name.Pluralize()} {{ get; set; }}"
            };

            codeDbContext.Members.Add(snippet);
        }
Beispiel #5
0
        public static Func <TEntity, TKey> GetEntityKeyFunction(IEntityTypeMetadata entityTypeMetadata)
        {
            if (s_entityKeyFunc != null)
            {
                return(s_entityKeyFunc);
            }

            Initialize(entityTypeMetadata);

            return(s_entityKeyFunc);
        }
        public static IEntitySetMetadata GetEntitySetFor(this IContainerMetadata containerMetadata, IEdmSchemaType edmSchemaType)
        {
            Contract.Requires <ArgumentNullException>(containerMetadata != null);
            Contract.Requires <ArgumentNullException>(edmSchemaType != null);

            IEntityTypeMetadata entityType = GetEntityType(containerMetadata, edmSchemaType);

            if (entityType == null)
            {
                return(null);
            }
            return(containerMetadata.EntitySets.SingleOrDefault(es => es.ElementTypeHierarchyMetadata.Contains(entityType)));
        }
		internal EntitySetMetadata(Type contextType, IContainerMetadata container, IEdmEntitySet edmEntitySet, IEntityTypeMetadata entityTypeMetadata, IEntityTypeMetadata[] entityTypeHierarchyMetadata)
		{
			Contract.Assert(container != null);
			Contract.Assert(edmEntitySet != null);
			Contract.Assert(entityTypeMetadata != null);
			Contract.Assert(entityTypeHierarchyMetadata != null);
			Contract.Assert(entityTypeHierarchyMetadata.Length >= 1);

			ContextType = contextType;
			ContainerMetadata = container;
			_edmEntitySet = edmEntitySet;
			ElementTypeMetadata = entityTypeMetadata;
			ElementTypeHierarchyMetadata = entityTypeHierarchyMetadata;
		}
Beispiel #8
0
        internal EntitySetMetadata(Type contextType, IContainerMetadata container, IEdmEntitySet edmEntitySet, IEntityTypeMetadata entityTypeMetadata, IEntityTypeMetadata[] entityTypeHierarchyMetadata)
        {
            Contract.Assert(container != null);
            Contract.Assert(edmEntitySet != null);
            Contract.Assert(entityTypeMetadata != null);
            Contract.Assert(entityTypeHierarchyMetadata != null);
            Contract.Assert(entityTypeHierarchyMetadata.Length >= 1);

            ContextType                  = contextType;
            ContainerMetadata            = container;
            _edmEntitySet                = edmEntitySet;
            ElementTypeMetadata          = entityTypeMetadata;
            ElementTypeHierarchyMetadata = entityTypeHierarchyMetadata;
        }
		private static Func<object, object> GetUntypedEntityKeyFunction(IEntityTypeMetadata entityTypeMetadata)
		{
			Contract.Assert(entityTypeMetadata != null);

			// Build a parameterized EntityKeyFunction<TEntity, TKey> to obtain the key function
			Type genericEntityKeyFunctionType;
			if (entityTypeMetadata.CountKeyProperties == 1)
			{	// Use the type of the single key
				genericEntityKeyFunctionType = typeof(EntityKeyFunction<,>).MakeGenericType(entityTypeMetadata.ClrType, entityTypeMetadata.SingleClrKeyProperty.PropertyType);
			}
			else
			{	// Use object for an anonymous type - needed for multi property keys
				genericEntityKeyFunctionType = typeof(EntityKeyFunction<,>).MakeGenericType(entityTypeMetadata.ClrType, typeof(object[]));
			}
			return genericEntityKeyFunctionType.InvokeStaticMethod("GetUntypedEntityKeyFunction", entityTypeMetadata) as Func<object, object>;
		}
Beispiel #10
0
        private static Func <object, object> GetUntypedEntityKeyFunction(IEntityTypeMetadata entityTypeMetadata)
        {
            Contract.Assert(entityTypeMetadata != null);

            // Build a parameterized EntityKeyFunction<TEntity, TKey> to obtain the key function
            Type genericEntityKeyFunctionType;

            if (entityTypeMetadata.CountKeyProperties == 1)
            {                   // Use the type of the single key
                genericEntityKeyFunctionType = typeof(EntityKeyFunction <,>).MakeGenericType(entityTypeMetadata.ClrType, entityTypeMetadata.SingleClrKeyProperty.PropertyType);
            }
            else
            {                   // Use object for an anonymous type - needed for multi property keys
                genericEntityKeyFunctionType = typeof(EntityKeyFunction <,>).MakeGenericType(entityTypeMetadata.ClrType, typeof(object[]));
            }
            return(genericEntityKeyFunctionType.InvokeStaticMethod("GetUntypedEntityKeyFunction", entityTypeMetadata) as Func <object, object>);
        }
Beispiel #11
0
        public static Func <object, object> GetUntypedEntityKeyFunction(IEntityTypeMetadata entityTypeMetadata)
        {
            Func <TEntity, TKey> entityKeyFunction = GetEntityKeyFunction(entityTypeMetadata);

            return(new Func <object, object>((object untypedEntity) =>
            {
                if (untypedEntity == null)
                {
                    throw new ArgumentNullException("entity");
                }
                TEntity entity = untypedEntity as TEntity;
                if (entity == null)
                {
                    throw new ArgumentException(string.Format("Entity must be type {0}; is type {1}.", typeof(TEntity), untypedEntity.GetType()), "entity");
                }
                return entityKeyFunction(entity);
            }));
        }
Beispiel #12
0
        private static void ExpandGenericNavigationActionsForAllNavigationProperties(IEnumerable <HttpActionDescriptor> navigationActions,
                                                                                     List <HttpActionDescriptor> expandedDescriptors,
                                                                                     List <HttpActionDescriptor> removeDescriptors,
                                                                                     Func <string, string> actionNameBuilder)
        {
            foreach (HttpActionDescriptor navigationAction in navigationActions)
            {
                ReflectedHttpActionDescriptor reflectedHttpActionDescriptor = navigationAction as ReflectedHttpActionDescriptor;
                if ((reflectedHttpActionDescriptor != null) &&
                    reflectedHttpActionDescriptor.MethodInfo.IsGenericMethodDefinition &&
                    reflectedHttpActionDescriptor.MethodInfo.GetGenericArguments().Length == 1)
                {
                    // Lookup the EntitySet metadata for the controller
                    IContainerMetadata containerMetadata = reflectedHttpActionDescriptor.ControllerDescriptor.GetContainerMetadata();
                    if (containerMetadata != null)
                    {
                        IEntitySetMetadata entitySetMetadata = containerMetadata.GetEntitySet(reflectedHttpActionDescriptor.ControllerDescriptor.ControllerName);
                        if (entitySetMetadata != null)
                        {
                            foreach (IEntityTypeMetadata entityTypeMetadata in entitySetMetadata.ElementTypeHierarchyMetadata)
                            {
                                // Foreach NavigationProperty in all of the entity types, add a new HttpActionDescriptor
                                foreach (var edmNavigationProperty in entityTypeMetadata.EdmType.DeclaredProperties.OfType <IEdmNavigationProperty>())
                                {
                                    IEdmEntityType      toEntityType         = edmNavigationProperty.ToEntityType();
                                    IEntityTypeMetadata propertyTypeMetadata = containerMetadata.GetEntityType(toEntityType);

                                    Type       tProperty          = propertyTypeMetadata.ClrType;
                                    MethodInfo genericMethod      = reflectedHttpActionDescriptor.MethodInfo.MakeGenericMethod(tProperty);
                                    string     expandedActionName = actionNameBuilder(edmNavigationProperty.Name);
                                    expandedDescriptors.Add(new RenamedReflectedHttpActionDescriptor(reflectedHttpActionDescriptor.ControllerDescriptor,
                                                                                                     genericMethod,
                                                                                                     expandedActionName));
                                }
                            }
                        }
                    }

                    removeDescriptors.Add(reflectedHttpActionDescriptor);
                }
            }
        }
Beispiel #13
0
        private IEntityTypeMetadata[] FindTypeHierarchyFrom(IEntityTypeMetadata root, IEntityTypeMetadata[] allEntityTypes)
        {
            ISet <Type> typeHierarchy = new HashSet <Type> {
                root.ClrType
            };
            bool newTypesAdded = true;

            // Keep looping until no more elements are found with parents in typeHierarchy
            while (newTypesAdded)
            {
                newTypesAdded = false;
                // Find types in allEntityTypes that are directly derived from types in typeHierarchy, but which are not in the typeHierarchy set; then add them
                var newDerivedTypes = allEntityTypes.Where(entityTypeMetadata => !typeHierarchy.Contains(entityTypeMetadata.ClrType) && typeHierarchy.Contains(entityTypeMetadata.ClrType.BaseType))
                                      .Select(entityTypeMetadata => entityTypeMetadata.ClrType);
                foreach (var derivedType in newDerivedTypes)
                {
                    newTypesAdded = true;                     // Loop again
                    typeHierarchy.Add(derivedType);
                }
            }

            return(allEntityTypes.Where(entityTypeMetadata => typeHierarchy.Contains(entityTypeMetadata.ClrType)).ToArray());
        }
Beispiel #14
0
        private static void Initialize(IEntityTypeMetadata entityTypeMetadata)
        {
            Contract.Requires <ArgumentNullException>(entityTypeMetadata != null);
            Contract.Requires <ArgumentException>(entityTypeMetadata.ClrKeyProperties != null);
            Contract.Requires <ArgumentException>(typeof(TEntity) == entityTypeMetadata.ClrType, "The TEntity type parameter doesn't match the entity type in the datamodel entitytype.");

            // Create a lambda expression that returns the property, and compile it
            Expression <Func <TEntity, TKey> > lambda;
            ParameterExpression param = Expression.Parameter(entityTypeMetadata.ClrType, "e");

            if (entityTypeMetadata.CountKeyProperties == 1)
            {                   // Single key, use a simple expression to return the key property
                lambda = Expression.Lambda <Func <TEntity, TKey> >(Expression.Property(param, entityTypeMetadata.SingleClrKeyProperty), param);
            }
            else
            {                                                                                                                                                         // Multiple keys, return an object array of the key values
                var keyProperties = entityTypeMetadata.ClrKeyProperties.Select(property => Expression.Convert(Expression.Property(param, property), typeof(object))); // TypeAs provides an (object) cast aka boxing, needed to convert value types to object
                lambda = Expression.Lambda <Func <TEntity, TKey> >(Expression.NewArrayInit(typeof(object), keyProperties), param);
            }
            Func <TEntity, TKey> func = lambda.Compile();

            // Store it
            Interlocked.CompareExchange(ref s_entityKeyFunc, func, null);
        }
Beispiel #15
0
        public static IQueryable <TEntity> QueryWhereKeyMatches(IQueryable <TEntity> queryable, TKey key, IEntityTypeMetadata entityTypeMetadata)
        {
            Contract.Requires <ArgumentNullException>(entityTypeMetadata != null);
            Contract.Requires <ArgumentException>(entityTypeMetadata.ClrKeyProperties != null);
            Contract.Requires <ArgumentException>(entityTypeMetadata.CountKeyProperties == 1);
            Contract.Requires <ArgumentException>(typeof(TEntity) == entityTypeMetadata.ClrType, "The TEntity type parameter doesn't match the entity type in the datamodel entitytype.");
            Contract.Requires <ArgumentException>(typeof(TKey) == entityTypeMetadata.SingleClrKeyProperty.PropertyType, "The TKey type parameter doesn't match the key type in the datamodel entitytype.");

            PropertyInfo keyProperty = entityTypeMetadata.SingleClrKeyProperty;

            // Create a lambda expression for (entity => entity{.KeyProperty} == key)
            ParameterExpression param = Expression.Parameter(entityTypeMetadata.ClrType, "e");
            var lambda = Expression.Lambda <Func <TEntity, bool> >(Expression.Equal(Expression.Property(param, keyProperty), Expression.Constant(key, typeof(TKey))), param);

            return(queryable.Where(lambda));
        }
        public static IEntitySetMetadata GetEntitySetFor(this IContainerMetadata containerMetadata, IEntityTypeMetadata entityTypeMetadata)
        {
            Contract.Requires <ArgumentNullException>(containerMetadata != null);
            Contract.Requires <ArgumentNullException>(entityTypeMetadata != null);

            return(containerMetadata.EntitySets.SingleOrDefault(es => es.ElementTypeMetadata.ClrType == entityTypeMetadata.ClrType));
        }
Beispiel #17
0
        public static Expression <Func <TEntity, IdAndNameResponseItem <Tkey> > > GetIdAndNameSelectionExpression <TEntity, Tkey>(IEntityTypeMetadata entityTypeMetadata)
        {
            var param = Expression.Parameter(typeof(TEntity), "s");
            var entityIdExpression = Expression.Property(param, entityTypeMetadata.GetPrimaryKey().Name);             //TODO:Hardcoded Primary key name
            var idType             = entityIdExpression.Type;
            var modelType          = typeof(IdAndNameResponseItem <>).MakeGenericType(idType);
            var idAssignment       = Expression.Bind(modelType.GetProperty(nameof(IdAndNameResponseItem <Tkey> .Id)), entityIdExpression);
            var displayNamePath    = entityTypeMetadata.DisplayNameProperty;

            if (string.IsNullOrWhiteSpace(displayNamePath))
            {
                displayNamePath = nameof(IdAndNameResponseItem <Tkey> .Id);
            }
            Expression path = param;

            foreach (var part in displayNamePath.Split('.'))
            {
                path = Expression.Property(path, part);
            }
            if (path.Type != typeof(string))
            {
                var type = path.Type;
                if (type != typeof(double) && type != typeof(double?) && type != typeof(decimal) && type != typeof(decimal?) && type != typeof(Guid) && type != typeof(Guid?))
                {
                    path = Expression.Convert(path, typeof(decimal?));
                    type = typeof(decimal?);
                }
                if (type.IsValueType && !type.IsGenericType)
                {
                    type = typeof(Nullable <>).MakeGenericType(type);
                    path = Expression.Convert(path, type);
                }
                path = Expression.Call(path, type.GetMethod(nameof(Object.ToString), Type.EmptyTypes));
            }
            var nameAssignment = Expression.Bind(typeof(NameResponseItem).GetProperty(nameof(NameResponseItem.DisplayName)), path);
            var selection      = Expression.MemberInit(Expression.New(modelType), idAssignment, nameAssignment);

            return(Expression.Lambda <Func <TEntity, IdAndNameResponseItem <Tkey> > >(selection, param));
        }
Beispiel #18
0
        public static IQueryable <TEntity> SortQuery <TEntity>(IOrderRequest request, IQueryable <TEntity> query, IEntityTypeMetadata entityTypeMetadata)
            where TEntity : class
        {
            var ordered = false;

            if (request.Order != null)
            {
                foreach (var order in request.Order)
                {
                    query   = query.Order(order.PropertyName, order.IsDescending, ordered);
                    ordered = true;
                }
            }
            if (!ordered)
            {
                query = query.Order(entityTypeMetadata.GetPrimaryKey().Name, true, ordered);
            }
            return(query);
        }
Beispiel #19
0
        public static Expression <Func <TEntity, bool> > FilterByIds <TEntity, TKey>(TKey[] ids, IEntityTypeMetadata entityTypeMetadata)
        {
            var param          = Expression.Parameter(typeof(TEntity), "i");
            var containsMethod = typeof(Enumerable).GetMethods().Single(x => x.Name == nameof(Enumerable.Contains) && x.GetParameters().Length == 2);

            containsMethod = containsMethod.MakeGenericMethod(typeof(TKey));
            var property = Expression.Property(param, entityTypeMetadata.GetPrimaryKey().Name);
            var idsExp   = Expression.Field(Expression.Constant(new IdsContainer <TKey> {
                Ids = ids
            }), nameof(IdsContainer <TKey> .Ids));
            var call   = Expression.Call(containsMethod, idsExp, property);
            var lambda = Expression.Lambda <Func <TEntity, bool> >(call, param);

            return(lambda);
        }