Esempio n. 1
0
        private bool IsDerivedCollection(Type CollectionType)
        {
            var itemType = TypesUtil.GetGenericArgumentForBaseType(CollectionType, typeof(IEnumerable <>));

            //if entityType is a non-entity, it will not have any mapping.
            return(typeTranslationUtil.GetMapping <IModelEntityMapping>(itemType) is IDerivedModelEntityMapping);
        }
Esempio n. 2
0
        public static object GetCollectionInstance(Type collectionType, List <object> collection)
        {
            //Arrays
            if (collectionType.IsArray)
            {
                var array = Activator.CreateInstance(collectionType, collection.Count) as Array;
                for (int i = 0; i < collection.Count; i++)
                {
                    array.SetValue(collection[i], i);
                }
                return(array);
            }

            //lists with indexers
            else if (collectionType.IsGenericType && collectionType.IsInterface && TypesUtil.IsNonPrimitiveCollection(collectionType))
            {
                var list = Activator.CreateInstance(typeof(List <>)
                                                    .MakeGenericType(TypesUtil.GetGenericArgumentForBaseType(collectionType, typeof(ICollection <>)))) as IList;
                collection.ForEach(item => list.Add(item));
                return(list);
            }

            //Custom generic collections .. assume they have default constructor and Add method
            else if (collectionType.IsGenericType && TypesUtil.IsNonPrimitiveCollection(collectionType) &&
                     collectionType.GetConstructor(Type.EmptyTypes) != null)
            {
                var customCollection = Activator.CreateInstance(collectionType);
                var addMethod        = collectionType.GetMethod("Add");
                collection.ForEach(item => addMethod.Invoke(customCollection, new object[] { item }));
                return(customCollection);
            }

            throw new NotSupportedException("Only Arrays, Lists, ICollection<> and Custom collection types with default constructor are supported.");
        }
Esempio n. 3
0
        public static SimpleType GetMember(SimpleType source, MemberExpression memberExp, MemberExpression translatedMemberExp, TypeTranslationUtil typeTranslationUtil)
        {
            SimpleType result;

            if (source != null)
            {
                result = source.GetMemberType(memberExp);
                if (result != null)
                {
                    return(result);
                }
            }

            var includes           = (source != null) ? source.GetMemberIncludes(memberExp) : new List <IncludeDirective>();
            var memberIsCollection = TypesUtil.IsNonPrimitiveCollection(memberExp.Type);

            var classMapping = typeTranslationUtil.GetMapping <IModelEntityMapping>(memberExp.Member.DeclaringType);

            if (memberIsCollection && classMapping != null)
            {
                //Getting the many-to-many maps for the declaringType
                var manyToManyRelationship = classMapping.GetManyToManyRelationships()
                                             .FirstOrDefault(m => ((MemberExpression)m.RelatedEntitySelector.Body).Member.Name == memberExp.Member.Name);
                if (manyToManyRelationship != null)
                {
                    var otherEndSelector           = manyToManyRelationship.RelatedEntitySelectorFromMap.Body as MemberExpression;
                    var param                      = Expression.Parameter(typeTranslationUtil.GetTranslatedType(manyToManyRelationship.MapType), "x");
                    var translatedOtherEndSelector = typeTranslationUtil.GetMemberExpression
                                                         (manyToManyRelationship.MapType, otherEndSelector.Member.Name, param);
                    var map = new ManyToManyMapType(manyToManyRelationship.MapType, param.Type,
                                                    TypesUtil.GetGenericArgumentForBaseType(memberExp.Type, typeof(ICollection <>)),
                                                    manyToManyRelationship, translatedOtherEndSelector.Member)
                    {
                        Includes = includes
                    };
                    return(new SimpleType(memberExp.Type, translatedMemberExp.Type)
                    {
                        NonPrimitiveEnumerableItemType = map
                    });
                }
            }

            result = new SimpleType(memberExp.Type, translatedMemberExp.Type);
            if (memberIsCollection)
            {
                var itemType           = TypesUtil.GetGenericArgumentForBaseType(memberExp.Type, typeof(IEnumerable <>));
                var translatedItemType = TypesUtil.GetGenericArgumentForBaseType(translatedMemberExp.Type, typeof(IEnumerable <>));
                var innerType          = new SimpleType(itemType, translatedItemType)
                {
                    Includes = includes
                };
                result.NonPrimitiveEnumerableItemType = innerType;
            }
            else
            {
                result.Includes = includes;
            }
            return(result);
        }
Esempio n. 4
0
        public void GetGenericArgumentForBaseType_BaseClass1()
        {
            Type finalType        = typeof(ArgForGetGenericArgumentForBaseType);
            Type specificBaseType = typeof(ArgForGetGenericArgumentForBaseTypeBase <>);
            Type expected         = typeof(string);
            Type actual;

            actual = TypesUtil.GetGenericArgumentForBaseType(finalType, specificBaseType);
            Assert.AreEqual(expected, actual);
        }
Esempio n. 5
0
        public void GetGenericArgumentForBaseType_ExceptionOnNonGenericInput()
        {
            Type finalType        = typeof(ArgForGetGenericArgumentForBaseType);
            Type specificBaseType = typeof(IEnumerable);
            Type expected         = typeof(int);
            Type actual;

            actual = TypesUtil.GetGenericArgumentForBaseType(finalType, specificBaseType);
            Assert.AreEqual(expected, actual);
        }
Esempio n. 6
0
 private SimpleType GetQueryableType(Type originalType, Type translatedType)
 {
     if (!TypesUtil.IsNonPrimitiveCollection(originalType))
     {
         return(new SimpleType(originalType, translatedType));
     }
     else
     {
         var itemType           = TypesUtil.GetGenericArgumentForBaseType(originalType, typeof(IEnumerable <>));
         var translatedItemType = TypesUtil.GetGenericArgumentForBaseType(translatedType, typeof(IEnumerable <>));
         return(RuntimeTypes.CreateEnumerable(new SimpleType(itemType, translatedItemType)));
     }
 }
Esempio n. 7
0
        private Func <EntityContext, object[], TResult> GetFunc <TResult>(LambdaExpression query)
        {
            var analyzer       = new CompilableQueryAnalyzer(query, GetTypeTranslationUtil());
            var analysisResult = analyzer.GetResult();

            //Find L2S.CompiledQuery.Compile<...>()
            //  and invoke the backend compiler; backendCompiledMethod is a Func<,..>
            var compiledBackendMethod = GetCompileMethod(analysisResult).Invoke(null, new object[] { analysisResult.TranslatedCompilableLambda });

            //Compile the client-side part of the expression and get a Func<>
            //  This function the materialized form and works on it (like call a ToList() for instance).
            object postMaterializationLambda = null;

            if (analysisResult.PostMaterializationLambda != null)
            {
                postMaterializationLambda = analysisResult.PostMaterializationLambda.Compile();
            }

            //l2sCompileResult lambda can return two types
            //  1. IQueryable
            //  2. An Entity itself, as a result of the call to First(), Single() etc.
            if (!TypesUtil.IsNonPrimitiveCollection(analysisResult.MaterializableExpression.Type))
            {
                return((context, args) =>
                {
                    var backendResults = InvokeCompiledMethod(compiledBackendMethod, context as EntityContext, args);

                    var singleObjectMaterializer = Activator.CreateInstance(typeof(SingleObjectMaterializer <>)
                                                                            .MakeGenericType(analysisResult.MaterializableExpression.Type), new object[] { context });

                    var materializedResult = singleObjectMaterializer.GetType().GetMethod("MakeResult")
                                             .Invoke(singleObjectMaterializer, new object[] { backendResults, analysisResult.QueryableType });

                    return (TResult)InvokePostMaterializationLambda_IfExists(materializedResult, postMaterializationLambda);
                });
            }
            else
            {
                return((context, args) =>
                {
                    var queryType = TypesUtil.GetGenericArgumentForBaseType(analysisResult.MaterializableExpression.Type, typeof(IQueryable <>));
                    var compiledQuery = Activator.CreateInstance(typeof(CompiledQuery <>).MakeGenericType(queryType),
                                                                 new object[] { GetQueryProvider(context as EntityContext), this, args, compiledBackendMethod, analysisResult.QueryableType.NonPrimitiveEnumerableItemType });

                    return (TResult)InvokePostMaterializationLambda_IfExists(compiledQuery, postMaterializationLambda);
                });
            }
        }
Esempio n. 8
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.
        }
Esempio n. 9
0
        //Make an enumerable of type enumerableType and fill it with items.
        private object MakeEnumerable(Type enumerableType, List <object> items)
        {
            if (enumerableType.IsGenericType && TypesUtil.GenericTypeIsAssignableFrom(enumerableType, typeof(ICollection <>)))
            {
                return(MakeListOfType(TypesUtil.GetGenericArgumentForBaseType(enumerableType, typeof(ICollection <>)), items));
            }

            else if (enumerableType.IsArray)
            {
                var list = MakeListOfType(enumerableType.GetElementType(), items);
                return(list.GetType().GetMethod("ToArray").Invoke(list, null));
            }

            else
            {
                throw new NotSupportedException("The collection of type " + enumerableType.ToString() + " cannot be bound to the context.");
            }
        }
Esempio n. 10
0
        public override PostProjectionLoadedResult GetResult(IUnprojectedBinding binding, List <object> objects)
        {
            var result = new PostProjectionLoadedResult();

            result.ProjectionBinding = binding;

            var targetType = TypesUtil.GetGenericArgumentForBaseType(binding.TargetBinding.Type, typeof(IEnumerable <>));

            Func <AnonymousType, object> valueGetter =
                ao => Get_GetProjectedValue_Computation(binding.TargetBinding)(new TableEntityRow(ao));

            var query = GetQuery(objects, valueGetter, targetType);

            query        = LoadIncludes(query, targetType, GetIncludes(binding));
            result.Value = MethodFinder.EnumerableMethods.ToList(targetType).Invoke(null, new object[] { query }) as IList;

            return(result);
        }
Esempio n. 11
0
        private void SetEnumerableProperty(object instance, PropertyInfo property, object items)
        {
            var propVal = property.GetValue(instance, null);

            if (property.PropertyType.IsArray || propVal == null)
            {
                property.SetValue(instance, items, null);
            }

            //If the instance is IEntity, we should go through Materialization methods to avoid triggering Reverse Reference setting.
            else if (instance is IEntity)
            {
                var intermediateInstance = (instance as IEntity)._getIntermediateEntity();

                var collectionOnIntermediate = intermediateInstance.GetType().GetProperty(property.Name)
                                               .GetValue(intermediateInstance) as IIntermediateEntityContainer;

                foreach (var item in (items as IEnumerable))
                {
                    collectionOnIntermediate.MaterializationAddReference((item as IEntity)._getIntermediateEntity());
                }
            }

            //Not an IEntity or an Array.
            //Assume this is a collection and call the "Add" method.
            else
            {
                var typeOfCollection = TypesUtil.GetGenericArgumentForBaseType(property.PropertyType, typeof(ICollection <>));

                var addMethod = propVal.GetType().GetMethod("Add", new Type[] { typeOfCollection });

                foreach (var item in items as IEnumerable)
                {
                    addMethod.Invoke(propVal, new object[] { item });
                }
            }
        }
Esempio n. 12
0
        private Func <object, TableEntityRow, object> Get_GetOrCreateEntityOrCollection_Computation(IncludeBinding includeBinding, MaterializationData data)
        {
            if (entityContext._InternalServices.TypeTranslationUtil.IsEntityCollection(includeBinding.Type))
            {
                var unprojectedBinding = data.ProjectedType.UnprojectedBindings
                                         .Find(ub => (ub is UnprojectedCollectionBinding || ub is UnprojectedManyToManyBinding) && ub.TargetBinding == includeBinding);
                if (unprojectedBinding != null)
                {
                    if (unprojectedBinding is UnprojectedManyToManyBinding)
                    {
                        return(Get_GetUnprojectedCollections_Computation(unprojectedBinding, data.ManyToManyMaps));
                    }
                    else
                    {
                        return(Get_GetUnprojectedCollections_Computation(unprojectedBinding, data.InheritanceChains));
                    }
                }
                else
                {
                    var collItemType = TypesUtil.GetGenericArgumentForBaseType(includeBinding.Type, typeof(ICollection <>));
                    var collectionEntityConstructor = new EntityConstructor(entityContext, collItemType);

                    return((tableEntity, source) =>
                    {
                        var list = new List <object>();
                        foreach (var item in (tableEntity as IEnumerable))
                        {
                            list.Add(collectionEntityConstructor.GetOrCreateEntity(new object[] { item }));
                        }
                        return list;
                    });
                }
            }

            return(Get_GetOrCreateEntity_Computation(includeBinding, data));
        }