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