Example #1
0
        public static TPOCO CreatePOCO <T, TPOCO>(this T source)
            where T : IModelEntity
            where TPOCO : IPOCO <T>, new()
        {
            Func <bool, object, bool, IPOCOContainer> getReferenceValue = (isEnumerable, propVal, isLoaded) =>
                                                                          isEnumerable ? (IPOCOContainer) new POCOCollection(propVal as IEnumerable, isLoaded)
                    : (IPOCOContainer) new POCOReference(propVal, isLoaded);

            TPOCO poco = new TPOCO();

            foreach (var prop in typeof(TPOCO).GetProperties())
            {
                var propOnSource = typeof(T).GetProperty(prop.Name);
                if (typeof(IPOCOContainer).IsAssignableFrom(prop.PropertyType))
                {
                    prop.SetValue(poco, getReferenceValue(TypesUtil.IsNonPrimitiveCollection(propOnSource.PropertyType),
                                                          propOnSource.GetValue(source), source._getIntermediateEntity().IsLoaded(makeFieldSelector <T>(propOnSource))));
                }
                else
                {
                    prop.SetValue(poco, propOnSource.GetValue(source));
                }
            }
            return(poco);
        }
Example #2
0
        //Fills an Enumerable (List, Collection etc) with items
        private object FillEnumerable(object enumerable, List <object> items)
        {
            var enumerableType = enumerable.GetType();

            if (enumerableType.IsArray) //Array
            {
                for (int i = 0; i < items.Count; i++)
                {
                    (enumerable as Array).SetValue(items[i], i);
                }
            }
            else if (typeof(IList).IsAssignableFrom(enumerableType))    //List and derived types .. which have indexers
            {
                for (int i = 0; i < items.Count; i++)
                {
                    (enumerable as IList)[i] = items[i];
                }
            }
            else if (enumerableType.IsGenericType && TypesUtil.IsNonPrimitiveCollection(enumerableType))  //Custom generic collections
            {
                enumerableType.GetMethod("Clear").Invoke(enumerable, null);
                var addMethod = enumerableType.GetMethod("Add");
                foreach (var item in items)
                {
                    addMethod.Invoke(enumerable, new object[] { item });
                }
            }
            else
            {
                throw new NotSupportedException("The collection of type " + enumerableType.ToString() + " cannot be bound to the context.");
            }

            return(enumerable);
        }
Example #3
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.");
        }
Example #4
0
        private List <IUnprojectedBinding> GetUnprojectedBindings(IEnumerable <IRequestedBinding> requestedBindings)
        {
            var result = new List <IUnprojectedBinding>();

            foreach (var target in requestedBindings.Where(b => TypesUtil.IsNonPrimitiveCollection(b.Type)))
            {
                if (target is UnprojectedIncludeInCollectionBinding)
                {
                    result.Add(target as IUnprojectedBinding);
                }
                //If the target is a collection, and the type of collection is inherited, we will do its loading
                //  via "Post-Projection Loader". Which reloads the inheritance chain by issuing a new query.
                //We will not handle this case here, instead just mark this for post projection loading.
                else if (TypesUtil.IsNonPrimitiveCollection(target.Type))
                {
                    if (IsManyToManyBinding(target))
                    {
                        var unprojected = new UnprojectedManyToManyBinding();
                        unprojected.TargetBinding = target;
                        result.Add(unprojected);
                    }
                    else
                    {
                        if (IsDerivedCollection(target.Type))
                        {
                            var unprojected = new UnprojectedCollectionBinding();
                            unprojected.TargetBinding = target;
                            result.Add(unprojected);
                        }
                    }
                }
            }

            return(result);
        }
Example #5
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);
        }
Example #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)));
     }
 }
Example #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);
                });
            }
        }
Example #8
0
        protected object LoadObject(IObjectGraph source, Dictionary <object, object> parsedObjects)
        {
            if (!source.IsAnonymous)
            {
                var instance = source.GetInstance();
                if (instance is IEntity)
                {
                    instance = GetCopyInContextOrAttach(instance as IEntity);
                }

                LoadIncludes(source, instance, parsedObjects);

                return(instance);
            }

            else
            {
                //Anonymous Types
                var anonType = source.GetInstanceType();
                var ctor     = anonType.GetConstructors().Single();

                var deserializedIncludes = new Dictionary <PropertyInfo, object>();

                foreach (var property in source.GetPropertiesNeedingContextBinding())
                {
                    if (!TypesUtil.IsNonPrimitiveCollection(property.PropertyType))
                    {
                        var propertyValue = LoadObject(source.GetObjectGraphForProperty(property), parsedObjects);
                        deserializedIncludes.Add(property, propertyValue);
                    }
                    else
                    {
                        var collectionItems = source.GetObjectGraphForCollection(property)
                                              .Select(itemInfo => LoadObject(itemInfo, parsedObjects)).ToList();

                        var propertyValue = MakeEnumerable(property.PropertyType, collectionItems);

                        deserializedIncludes.Add(property, propertyValue);
                    }
                }

                var ctorArgs = deserializedIncludes.Select(kvp => kvp.Value).ToArray();

                return(Activator.CreateInstance(anonType, ctorArgs));
            }
        }
Example #9
0
        public object SwitchContext(object objects)
        {
            var returnType    = objects.GetType();
            var parsedObjects = new Dictionary <object, object>();

            if (!TypesUtil.IsNonPrimitiveCollection(returnType))
            {
                return(LoadObject(new InMemoryInstanceGraph(objects), parsedObjects));
            }
            else
            {
                var list = new List <object>();
                foreach (var objSource in objects as IEnumerable)
                {
                    list.Add(LoadObject(new InMemoryInstanceGraph(objSource), parsedObjects));
                }

                return(FillEnumerable(objects, list));
            }
        }
Example #10
0
        private List <IRelatedBinding> GetInheritanceBindings(IEnumerable <IRequestedBinding> requestedBindings)
        {
            var result = new List <IRelatedBinding>();

            foreach (var target in requestedBindings.Where(b => !TypesUtil.IsNonPrimitiveCollection(b.Type)))
            {
                //Not a collection. Add Inheritance Bindings if there are any.
                var inheritanceExpressions = GetInheritanceExpressions(target.Type, target.TranslatedExpression);
                foreach (var expression in inheritanceExpressions)
                {
                    var binding = new InheritanceBinding
                    {
                        TargetBinding        = target,
                        TranslatedExpression = expression
                    };

                    result.Add(binding);
                }
            }

            return(result);
        }
Example #11
0
        protected virtual List <IncludeDirective> GetMemberIncludes(MemberExpression memberExp)
        {
            var newIncludes           = new List <IncludeDirective>();
            var memberIsNotCollection = !TypesUtil.IsNonPrimitiveCollection(memberExp.Type);

            Includes.ForEach(inc =>
            {
                var includeExpression = inc.GetSelector().Body as MemberExpression;
                if (memberIsNotCollection)
                {
                    var innermostMember = ExpressionUtil.GetInnermostMemberExpression(includeExpression);
                    if (innermostMember.Member == memberExp.Member && includeExpression.Expression is MemberExpression)
                    {
                        var slicedExpression = ExpressionUtil.ReplaceInnermostMemberExpressionWithParameter(includeExpression) as MemberExpression;

                        if (inc is IIncludeInCollectionDirective)
                        {
                            newIncludes.Add(IncludeDirectiveUtil.GetIncludeInCollectionDirective(slicedExpression,
                                                                                                 (inc as IIncludeInCollectionDirective).GetFieldSelector()));
                        }
                        else
                        {
                            newIncludes.Add(IncludeDirectiveUtil.GetIncludeDirective(slicedExpression));
                        }
                    }
                }
                else
                {
                    if (inc is IIncludeInCollectionDirective && ExpressionUtil.IsEquivalent(inc.GetSelector().Body, memberExp))
                    {
                        newIncludes.Add(IncludeDirectiveUtil.GetIncludeDirective
                                            ((inc as IIncludeInCollectionDirective).GetFieldSelector()));
                    }
                }
            });
            return(newIncludes);
        }
Example #12
0
        protected void LoadIncludes(IObjectGraph source, object instance, Dictionary <object, object> parsedObjects)
        {
            if (parsedObjects.ContainsKey(instance))
            {
                return;
            }

            //Add it to the parsed objects list, so that we can avoid going through circular relationships.
            parsedObjects.Add(instance, null);

            if (source.IsCollection)
            {
                var sourceCollection = source.GetSourceCollection();
                var ctr = 0;
                foreach (var item in (instance as IEnumerable))
                {
                    LoadIncludes(sourceCollection[ctr++], item, parsedObjects);
                }
            }
            else
            {
                foreach (var property in source.GetPropertiesNeedingContextBinding())
                {
                    if (!TypesUtil.IsNonPrimitiveCollection(property.PropertyType))
                    {
                        //If the instance is an Entity, we treat property setting differently.
                        //  This is because setters will automatically trigger Reverse Reference setters.
                        if (instance is IEntity)
                        {
                            var propValFromSource = source.GetPropertyValue(property);
                            var loadedValue       = property.GetValue(instance);

                            //If the property is already loaded in our current instance, we should not touch it.
                            //  Yet, if they (current instance and the source) refer to the same value, we should attach includes.
                            //If they are NOT the same, we do nothing. (Since the user changed the property, can't overwrite.)
                            if (IsPropertyLoadedOnEntity(instance, property))
                            {
                                if (loadedValue != null && loadedValue is IEntity &&
                                    ((IEntity)loadedValue).IsEquivalent((IEntity)propValFromSource))
                                {
                                    LoadIncludes(source.GetObjectGraphForProperty(property), loadedValue, parsedObjects);
                                }
                            }

                            //Property is not loaded on the current instance. Go ahead and add it via Materialization methods.
                            else
                            {
                                if (source.GetPropertyValue(property) != null)
                                {
                                    var propertyValue         = LoadObject(source.GetObjectGraphForProperty(property), parsedObjects);
                                    var intermediateContainer = GetBackingContainerForProperty(instance as IEntity, property);
                                    intermediateContainer.MaterializationAddReference((propertyValue as IEntity)._getIntermediateEntity());
                                }
                            }
                        }

                        //Instance is not an IEntity, we can just set the property value.
                        else
                        {
                            if (source.GetPropertyValue(property) != null)
                            {
                                var propertyValue = LoadObject(source.GetObjectGraphForProperty(property), parsedObjects);
                                property.SetValue(instance, propertyValue);
                            }
                        }
                    }

                    //This property is a collection.
                    else
                    {
                        var entityList = source.GetObjectGraphForCollection(property)
                                         .Select(collItemSource => LoadObject(collItemSource, parsedObjects)).ToList();

                        if (IsManyToMany(property))
                        {
                            //Many-to-Many collection can only exist in Entities, hence the cast.
                            AddToManyToManyCollection((IEntity)instance, property, entityList);
                        }
                        else
                        {
                            SetEnumerableProperty(instance, property, MakeEnumerable(property.PropertyType, entityList));
                        }
                    }
                }
            }
        }
Example #13
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);
            }
        }
Example #14
0
        private void AddIncludes(SerializableObjectGraph objectGraph, MemberExpression includedPropertyChain, IEnumerable <MemberExpression> collectionIncludes)
        {
            var memberExp = ExpressionUtil.GetInnermostMemberExpression(includedPropertyChain);
            var propInfo  = objectGraph.GetInstance().GetType().GetProperty(memberExp.Member.Name);

            if (IsPropertyLoadedOnEntity(objectGraph.GetInstance(), propInfo))
            {
                var propVal = propInfo.GetValue(objectGraph.GetInstance(), null);
                if (propVal == null)
                {
                    return;
                }

                if (TypesUtil.IsNonPrimitiveCollection(propInfo.PropertyType))
                {
                    var collInclude = objectGraph.IncludedMembers.ContainsKey(propInfo) ?
                                      objectGraph.IncludedMembers[propInfo] : null;

                    if (collInclude == null)
                    {
                        var list = new List <IObjectGraph>();

                        foreach (var item in (propVal as IEnumerable))
                        {
                            list.Add(new SerializableInstance {
                                Object = item, InstanceType = item.GetType()
                            });
                        }

                        collInclude = new SerializableCollection
                        {
                            Collection   = list,
                            InstanceType = propInfo.PropertyType
                        };

                        objectGraph.IncludedMembers.Add(propInfo, collInclude);
                    }

                    if (collectionIncludes != null)
                    {
                        foreach (SerializableObjectGraph instanceWrapper in (collInclude as SerializableCollection).Collection)
                        {
                            foreach (var include in collectionIncludes)
                            {
                                AddIncludes(instanceWrapper, include, null);
                            }
                        }
                    }
                }
                else
                {
                    var fieldInclude = objectGraph.IncludedMembers.ContainsKey(propInfo) ?
                                       objectGraph.IncludedMembers[propInfo] : null;

                    if (fieldInclude == null)
                    {
                        fieldInclude = new SerializableInstance {
                            Object = propVal, InstanceType = propInfo.PropertyType
                        };
                        objectGraph.IncludedMembers.Add(propInfo, fieldInclude);
                    }

                    if (includedPropertyChain.GetDepth() > 1)
                    {
                        AddIncludes(fieldInclude,
                                    ExpressionUtil.ReplaceInnermostMemberExpression(includedPropertyChain, Expression.Parameter(memberExp.Type, "x")) as MemberExpression,
                                    collectionIncludes);
                    }
                }
            }
        }