예제 #1
0
        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));
            }
        }
예제 #2
0
        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.
        }
예제 #3
0
 //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());
     }
 }
예제 #4
0
        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));
            }
        }
예제 #5
0
        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));
        }
예제 #6
0
        //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);
            }
        }