public virtual IEnumerable <T> GetResultList(Expression expression) { var visitor = new QueryTranslationVisitor(new QueryAnalysisContext(entityContext._InternalServices.TypeTranslationUtil) { ModifyProjection = true }); var translationResults = visitor.GetTranslatedResults(expression); var tableEntityQuery = translationResults.AnalysisContext.RootEntityQuery.TableEntityQuery .Provider.CreateQuery(translationResults.TranslatedExpression); if (TypesUtil.IsPrimitiveDataType(typeof(T))) { return(tableEntityQuery as IEnumerable <T>); } else { var tableEntities = new List <object>(); foreach (object o in tableEntityQuery) { tableEntities.Add(o); } return(MakeResultList(tableEntities, translationResults.AnalysisContext.QueryableType.NonPrimitiveEnumerableItemType)); } }
private bool NeedsProjectionModification(Expression currentExpression) { //Get the T, when the query returns T or IQueryable<T> var genericTypeOfResult = typeof(IQueryable).IsAssignableFrom(currentExpression.Type) ? TypesUtil.GetGenericArgumentForBaseType(currentExpression.Type, typeof(IQueryable <>)) : currentExpression.Type; //If this is the outermost method, and it is a Non-Primitive Type, we need to modify the Projection // so that we can add implicit includes (like Inhertiance) and user-requested Includes (Prefetch Paths) //There are two cases: // 1) If IQueryable<NonPrimitiveType>, add a Select around translated mce (eg: Where, Select etc) // 2) If just NonPrimitiveType, add a Select around translatedFirstArg (eg: First, Single etc) return(AnalysisContext.ModifyProjection && //Don't modify if context.ModifyProjection is false !(AnalysisContext.QueryableType.NonPrimitiveEnumerableItemType is ProjectedType) && //Don't modify if already modified, that is - context.QueryableType is ProjectedType !TypesUtil.IsPrimitiveDataType(genericTypeOfResult)); //Don't modify if Primitive Type. }
//All Entities need to be bound to the context. public PropertyInfo[] GetPropertiesNeedingContextBinding() { if (source == null) { return(null); } if (source is IEntity) { return(source.GetType().GetProperties() .Where(p => typeof(IEntity).IsAssignableFrom(p.PropertyType) || typeof(IEntityCollection).IsAssignableFrom(p.PropertyType)).ToArray()); } else { return(source.GetType().GetProperties().Where(p => !TypesUtil.IsPrimitiveDataType(p.PropertyType)).ToArray()); } }
public virtual T GetResult(Expression expression) { var visitor = new QueryTranslationVisitor(new QueryAnalysisContext(entityContext._InternalServices.TypeTranslationUtil) { ModifyProjection = true }); var translationResults = visitor.GetTranslatedResults(expression); var tableEntityQuery = translationResults.AnalysisContext.RootEntityQuery.TableEntityQuery; var tableEntity = tableEntityQuery.Provider.Execute(translationResults.TranslatedExpression); if (TypesUtil.IsPrimitiveDataType(typeof(T))) { return((T)tableEntity); } else { return(MakeResult(tableEntity, translationResults.AnalysisContext.QueryableType)); } }
public ProjectionModification GetModifiedProjection() { //There will be no includes or inheritance bindings on primitive types (like int, long, guid etc) //We can just return the current expression, and QueryableType. if (TypesUtil.IsPrimitiveDataType(currentExpression.Type)) { return new ProjectionModification { ModifiedExpression = currentExpression, QueryableType = queryableType } } ; var parameter = Expression.Parameter(queryableType.NonPrimitiveEnumerableItemType.TranslatedType, "p"); var queryBindings = GetQueryBindings(queryableType.NonPrimitiveEnumerableItemType, parameter); var includeBindings = GetIncludeBindings(queryBindings); var requestedBindings = new List <IRequestedBinding>(); queryBindings.ForEach(b => requestedBindings.Add(b)); includeBindings.ForEach(b => requestedBindings.Add(b)); var inheritanceBindings = GetInheritanceBindings(requestedBindings); var unprojectedBindings = GetUnprojectedBindings(requestedBindings); var relatedBindings = new List <IRelatedBinding>(); //Add all related bindings to the context. //We don't need QueryBindings since they are just a wrapped around QueryableTypes includeBindings.Where(inc => !(inc is UnprojectedIncludeInCollectionBinding)).ToList() .ForEach(inc => relatedBindings.Add(inc)); inheritanceBindings.ForEach(b => relatedBindings.Add(b)); //All set. Create the new Select Expression. return(CreateMethodCallExpression(parameter, relatedBindings, unprojectedBindings)); }
//Serialization of entities should consider the included fields. // - If A.B is defined as an include on A at the time of materialization, B should also be serialized // and re-attached when A is deserialized. private SerializableObjectGraph CreateObjectGraph(object entity) { var sourceType = entity.GetType(); //If this is a collection, create a graph for each item in the collection. if (TypesUtil.IsNonPrimitiveCollection(sourceType)) { var list = new List <IObjectGraph>(); foreach (object obj in entity as IEnumerable) { list.Add(CreateObjectGraph(obj)); } return(new SerializableCollection { Collection = list, InstanceType = sourceType }); } else { var serializableInstance = new SerializableInstance { Object = entity, InstanceType = entity.GetType() }; if (entity is IEntity) { var materializationIncludes = GetIncludeExpressions((entity as IEntity)._getIntermediateEntity().IncludeDirectives); foreach (var includeExps in materializationIncludes) { AddIncludes(serializableInstance, includeExps.FieldChain, includeExps.IncludesInCollection); } } else { if (TypesUtil.IsCompilerGeneratedAnonymousType(sourceType)) { serializableInstance.Object = null; serializableInstance.InstanceType = sourceType; } var properties = (entity is IEntity) ? sourceType.GetProperties() .Where(p => typeof(IEntity).IsAssignableFrom(p.PropertyType) || typeof(IEntityCollection).IsAssignableFrom(p.PropertyType)).ToArray() : (TypesUtil.IsPrimitiveDataType(sourceType) || sourceType.IsArray || TypesUtil.IsNonPrimitiveCollection(sourceType) ? new PropertyInfo[] {} : sourceType.GetProperties()); foreach (var prop in properties) { var propVal = prop.GetValue(entity, null); //Primitive types can be stored as is. if (TypesUtil.IsPrimitiveDataType(prop.PropertyType)) { serializableInstance.IncludedMembers.Add ( prop, new SerializableInstance { Object = propVal, InstanceType = prop.PropertyType } ); continue; } //This is a single object (possibly an entity); but not a primitive type or a collection if (!TypesUtil.IsNonPrimitiveCollection(prop.PropertyType)) { serializableInstance.IncludedMembers.Add ( prop, CreateObjectGraph(propVal) ); } //Collection of non-primitive types else if (TypesUtil.IsNonPrimitiveCollection(prop.PropertyType)) { var itemsInCollection = new List <IObjectGraph>(); foreach (var item in (propVal as IEnumerable)) { itemsInCollection.Add(CreateObjectGraph(item)); } serializableInstance.IncludedMembers.Add ( prop, new SerializableCollection { Collection = itemsInCollection, InstanceType = prop.PropertyType } ); } } } return(serializableInstance); } }