コード例 #1
0
        //Get base class objects corresponding to a given IncludeBinding.
        private Func <TableEntityRow, object[]> Get_GetBaseObjects_Computation(MaterializationData data,
                                                                               Predicate <IRelatedBinding> comparer)
        {
            var fieldIndexes = new List <int>();

            for (int i = 0; i < data.ProjectedType.RelatedBindings.Count; i++)
            {
                var b = data.ProjectedType.RelatedBindings[i];
                if (b is InheritanceBinding && comparer(b))
                {
                    fieldIndexes.Add(i + 1);
                }
            }
            return(source => fieldIndexes.Select(idx => source.Values[idx]).ToArray());
        }
コード例 #2
0
 private Func <object, TableEntityRow, object> Get_GetOrCreateEntityOrCollection_Computation(SimpleType trackedType, MaterializationData data)
 {
     if (trackedType is ProjectedType)
     {
         return(Get_HandleProjectedType_Computation(trackedType, data));
     }
     else if (trackedType.Constructor != null)
     {
         return(Get_CreateTypeWithConstructor_Computation(trackedType, data));
     }
     //When EnumerableItemType is not null... eg. Collections
     else if (trackedType.NonPrimitiveEnumerableItemType != null)
     {
         return(Get_CreateCollection_Computation(trackedType, data));
     }
     //Simple Entities
     else if (typeof(IEntity).IsAssignableFrom(trackedType.Type))
     {
         return(Get_GetOrCreateSimpleEntity_Computation(trackedType, data));
     }
     //Primitive types.. eg. int, long, string. Leave as is.
     else
     {
         return(Get_CreatePrimitiveType_Computation());
     }
 }
コード例 #3
0
 //Get base class objects corresponding to a given TrackedType.
 private Func <TableEntityRow, object[]> Get_GetBaseObjects_Computation(SimpleType trackedType, MaterializationData data)
 {
     return(Get_GetBaseObjects_Computation(data, b => b.MatchesTarget(trackedType)));
 }
コード例 #4
0
 //Get base class objects corresponding to a given IncludeBinding.
 private Func <TableEntityRow, object[]> Get_GetBaseObjects_Computation(IncludeBinding binding, MaterializationData data)
 {
     return(Get_GetBaseObjects_Computation(data, b => b.MatchesTarget(binding)));
 }
コード例 #5
0
        private Action <object, TableEntityRow> Get_AttachIncludes_Computation(SimpleType trackedType, MaterializationData data)
        {
            var includeBindings = data.ProjectedType.RelatedBindings
                                  .Where(b => b is IncludeBinding && (b.TargetBinding is QueryBinding) &&
                                         (b.TargetBinding as QueryBinding).Value == trackedType).Cast <IncludeBinding>().ToList();

            var attachIncludes = includeBindings.Select(b => Get_AttachIncludes_Computation(trackedType.Type, b, data)).ToList();

            return((entity, source) =>
            {
                attachIncludes.ForEach(f => f(entity, source));
            });
        }
コード例 #6
0
        private Action <object, TableEntityRow> Get_AttachIncludes_Computation(Type entityType, IncludeBinding includeBinding
                                                                               , MaterializationData data)
        {
            var includeBindings = data.ProjectedType.RelatedBindings
                                  .Where(b => b is IncludeBinding && b.TargetBinding == includeBinding).Cast <IncludeBinding>().ToList();
            var setIncludes = includeBindings.Select(b => Get_AttachIncludes_Computation(includeBinding.Type, b, data)).ToList();

            //The fieldNo is 1 more than the related-binding index; since the first field [0] is the main entity itself.
            var fieldNo = data.ProjectedType.RelatedBindings.IndexOf(includeBinding) + 1;

            var getOrCreateEntityOrCollection = Get_GetOrCreateEntityOrCollection_Computation(includeBinding, data);
            var memberInfo = (includeBinding.IncludeDirective.GetSelector().Body as MemberExpression).Member;

            //Handling Many-to-Many Map type separately
            if (entityContext._InternalServices.TypeTranslationUtil.GetMapping <IMapEntityMapping>(entityType) != null)
            {
                return((parent, source) =>
                {
                    //Setting the include directive in the intermediate object
                    (parent as IEntity)._getIntermediateEntity().IncludeDirectives.Add(includeBinding.IncludeDirective);

                    var valueInProjection = source.Values[fieldNo];
                    var memberValue = getOrCreateEntityOrCollection(valueInProjection, source);
                    memberInfo.SetValue(parent, memberValue);
                    setIncludes.ForEach(f => f(memberValue, source));
                });
            }

            //Not a Many-to-Many Collection
            else
            {
                var backingContainerGetter = entityContext._InternalServices.TypeTranslationUtil
                                             .MakeBackingContainerGetter(entityType, memberInfo);

                return((parent, source) =>
                {
                    //Setting the include directive in the intermediate object
                    (parent as IEntity)._getIntermediateEntity().IncludeDirectives.Add(includeBinding.IncludeDirective);

                    var valueInProjection = source.Values[fieldNo];
                    var intermediateContainerOnParent = backingContainerGetter((parent as IEntity)._getIntermediateEntity());
                    var memberValue = getOrCreateEntityOrCollection(valueInProjection, source);

                    if (null == memberValue)
                    {
                        return;
                    }

                    if (memberValue is IList)
                    {
                        foreach (var entity in (memberValue as IList))
                        {
                            intermediateContainerOnParent.MaterializationAddReference((entity as IEntity)._getIntermediateEntity());
                        }
                    }
                    else
                    {
                        intermediateContainerOnParent.MaterializationAddReference((memberValue as IEntity)._getIntermediateEntity());
                    }
                    var member = memberInfo.GetValue(parent);
                    setIncludes.ForEach(f => f(member, source));
                });
            }
        }
コード例 #7
0
        Get_GetMembers_Computation(Dictionary <MemberInfo, SimpleType> memberQuerableTypes, SimpleType trackedType, MaterializationData data)
        {
            var members = new Dictionary <MemberInfo, KeyValuePair <Func <object, object>, Func <object, TableEntityRow, object> > >();

            foreach (var memberInfo in memberQuerableTypes.Keys)
            {
                members.Add(memberInfo, new KeyValuePair <Func <object, object>, Func <object, TableEntityRow, object> >
                                (trackedType.GetTranslatedMemberValue(memberInfo, entityContext._InternalServices.TypeTranslationUtil),
                                Get_GetOrCreateEntityOrCollection_Computation(memberQuerableTypes[memberInfo], data)));
            }
            return(members);
        }
コード例 #8
0
        private Func <object, TableEntityRow, object> Get_GetOrCreateEntity_Computation(IncludeBinding includeBinding, MaterializationData data)
        {
            var getbaseObjects    = Get_GetBaseObjects_Computation(includeBinding, data);
            var entityConstructor = new EntityConstructor(entityContext, includeBinding.Type);

            return((projectedEntity, source) =>
            {
                if (projectedEntity == null)
                {
                    return null;
                }
                var tableObjects = new List <object>();
                tableObjects.Add(projectedEntity);
                tableObjects.AddRange(getbaseObjects(source));
                return entityConstructor.GetOrCreateEntity(tableObjects.ToArray());
            });
        }
コード例 #9
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));
        }
コード例 #10
0
        //Simple Entities
        private Func <object, TableEntityRow, object> Get_GetOrCreateSimpleEntity_Computation(SimpleType trackedType, MaterializationData data)
        {
            var getOrCreateEntity = Get_GetOrCreateEntity_Computation(trackedType, data);
            var attachIncludes    = Get_AttachIncludes_Computation(trackedType, data);

            return((projectedEntity, source) =>
            {
                var newObj = getOrCreateEntity(projectedEntity, source);
                attachIncludes(newObj, source);
                return newObj;
            });
        }
コード例 #11
0
        //When EnumerableItemType is not null... eg. Collections
        private Func <object, TableEntityRow, object> Get_CreateCollection_Computation(SimpleType trackedType, MaterializationData data)
        {
            var collectionType = typeof(List <>).MakeGenericType(trackedType.NonPrimitiveEnumerableItemType.Type);

            if (entityContext._InternalServices.TypeTranslationUtil.IsEntityCollection(trackedType.Type))
            {
                var unprojectedBinding = data.ProjectedType.UnprojectedBindings
                                         .Find(ub => (ub is UnprojectedCollectionBinding || ub is UnprojectedManyToManyBinding) &&
                                               ub.TargetBinding is QueryBinding && (ub.TargetBinding as QueryBinding).Value == trackedType);
                if (unprojectedBinding != null)
                {
                    var getUnprojectedCollection = Get_GetUnprojectedCollections_Computation(unprojectedBinding,
                                                                                             (unprojectedBinding is UnprojectedManyToManyBinding) ? data.ManyToManyMaps : data.InheritanceChains);

                    if (unprojectedBinding is UnprojectedManyToManyBinding)
                    {
                        var mappingMember = (trackedType.NonPrimitiveEnumerableItemType as ManyToManyMapType).Mapping.Name;
                        return((projectedEntity, source) =>
                        {
                            var maps = getUnprojectedCollection(projectedEntity, source);
                            var list = Activator.CreateInstance(collectionType) as IList;
                            foreach (var map in (maps as IList))
                            {
                                list.Add(map.GetType().GetProperty(mappingMember).GetValue(map));
                            }
                            return list;
                        });
                    }
                    else
                    {
                        return(getUnprojectedCollection);
                    }
                }
            }

            var getOrCreateEntity = Get_GetOrCreateEntityOrCollection_Computation(trackedType.NonPrimitiveEnumerableItemType, data);
            var attachIncludes    = Get_AttachIncludes_Computation(trackedType, data);

            return((projectedEntity, source) =>
            {
                var list = Activator.CreateInstance(collectionType) as IList;
                foreach (var collItem in (projectedEntity as IEnumerable))
                {
                    list.Add(getOrCreateEntity(collItem, source));
                }
                attachIncludes(list, source);
                return list;
            });
        }
コード例 #12
0
        //Where the user has mentioned a specific constructor in the query.
        private Func <object, TableEntityRow, object> Get_CreateTypeWithConstructor_Computation(SimpleType trackedType, MaterializationData data)
        {
            var fields          = new Dictionary <MemberInfo, KeyValuePair <Func <object, object>, Func <object, TableEntityRow, object> > >();
            var constructorArgs = new Dictionary <MemberInfo, KeyValuePair <Func <object, object>, Func <object, TableEntityRow, object> > >();

            if (TypesUtil.IsCompilerGeneratedAnonymousType(trackedType.Type))
            {
                constructorArgs = Get_GetMembers_Computation(trackedType.GetAllMembers(), trackedType, data);
            }
            else
            {
                fields = Get_GetMembers_Computation(trackedType.Fields, trackedType, data);
            }

            Action <object, object, TableEntityRow> setCollectionItems = (newObj, projectedEntity, source) => { };

            if (trackedType.NonPrimitiveEnumerableItemType != null)
            {
                var getOrCreateCollectionItem = Get_GetOrCreateEntityOrCollection_Computation(trackedType.NonPrimitiveEnumerableItemType, data);
                var addMethod = trackedType.Constructor.DeclaringType.GetMethod("Add", new Type[] { trackedType.NonPrimitiveEnumerableItemType.Type });
                setCollectionItems = (newObj, projectedEntity, source) =>
                {
                    foreach (var tableCollectionItem in (projectedEntity as IEnumerable))
                    {
                        var collItem = getOrCreateCollectionItem(tableCollectionItem, source);
                        addMethod.Invoke(newObj, new object[] { collItem });
                    }
                };
            }

            Action <object, MemberInfo, object> setMemberValue = (obj, m, val) => trackedType.Constructor.DeclaringType.GetProperty(m.Name).SetValue(obj, val);

            return((projectedEntity, source) =>
            {
                var args = constructorArgs.Select(kvp => kvp.Value.Value(kvp.Value.Key(projectedEntity), source)).ToArray();
                var newObj = trackedType.Constructor.Invoke(args);
                foreach (var fld in fields)
                {
                    setMemberValue(newObj, fld.Key, fld.Value.Value(fld.Value.Key(projectedEntity), source));
                }
                setCollectionItems(newObj, projectedEntity, source);
                return newObj;
            });
        }
コード例 #13
0
        //If the ProjectedType appears again in the Type-Tracking Tree, handle it.
        private Func <object, TableEntityRow, object> Get_HandleProjectedType_Computation(SimpleType trackedType, MaterializationData data)
        {
            var valueGetter = Get_FindValueInTreeMatchingTrackedType_Computation(data.ProjectedType, trackedType);
            var newResults  = data.ResultSet.Select(result => valueGetter(result)).ToList();

            var getProjectionValue = Get_GetProjection_Computation(trackedType as ProjectedType, newResults);

            return((tableEntity, source) =>
            {
                var newRow = new TableEntityRow(tableEntity as AnonymousType);
                return getProjectionValue(newRow.Values[0], newRow);
            });
        }