Beispiel #1
0
        public ICollection <T> ExtractTargetEntities <T, S>(IEnumerable <S> sourceEntities, String sourceToTargetEntityPropertyPath)
        {
            // Einen Accessor ermitteln, der die gesamte Hierachie aus dem propertyPath („A.B.C“) selbstständig traversiert
            Member member = MemberTypeProvider.GetMember(typeof(S), sourceToTargetEntityPropertyPath);

            // MetaDaten der Ziel-Entity ermitteln, da wir (generisch) den PK brauchen, um damit ein DISTINCT-Behavior durch eine Map als Zwischenstruktur zu
            // erreichen
            IEntityMetaData targetMetaData = EntityMetaDataProvider.GetMetaData(member.ElementType);
            PrimitiveMember targetIdMember = targetMetaData.IdMember;

            // Damit bei der Traversion keine Initialisierungen mit DB-Roundtrips entstehen, machen wir vorher eine Prefetch passend zum PropertyPath auf allen
            // übergebenen Quell-Entities
            // Dadurch entstehen maximal 2 gebatchte SELECTs, egal wie groß die Liste ist
            IPrefetchHandle prefetch = CreatePrefetch().Add(typeof(S), sourceToTargetEntityPropertyPath).Build();
            // Speichere das State-Result unbenutzt - wichtig für concurrent GC Aktivitäten, um Verluste an Entity-Referenzen zu verhindern
            IPrefetchState state = prefetch.Prefetch(sourceEntities);

            IDictionary <Object, T> targetDistinctMap = new Dictionary <Object, T>();

            // Danach traversieren, wobei wir jetzt wissen, dass uns das keine Roundtrips kostet
            foreach (S sourceEntity in sourceEntities)
            {
                if (sourceEntity == null)
                {
                    continue;
                }
                Object targetEntities = member.GetValue(sourceEntity);
                if (targetEntities == null)
                {
                    continue;
                }
                // Ergebnismenge flexibel (bei *-To-Many) verarbeiten oder so lassen (bei *-To-One)
                if (targetEntities is IEnumerable)
                {
                    foreach (Object targetEntity in (IEnumerable)targetEntities)
                    {
                        if (targetEntity == null)
                        {
                            continue;
                        }
                        Object targetId = targetIdMember.GetValue(targetEntity);
                        if (targetId == null)
                        {
                            // Falls die Entity keine ID hat, speichern wir sie ausnahmsweise selbst als Key
                            targetId = targetEntity;
                        }
                        targetDistinctMap[targetId] = (T)targetEntity;
                    }
                }
                else
                {
                    Object targetId = targetIdMember.GetValue(targetEntities);
                    if (targetId == null)
                    {
                        // Falls die Entity keine ID hat, speichern wir sie ausnahmsweise selbst als Key
                        targetId = targetEntities;
                    }
                    targetDistinctMap[targetId] = (T)targetEntities;
                }
            }
            // Alle values sind unsere eindeutigen Target Entities ohne Duplikate
            return(targetDistinctMap.Values);
        }
Beispiel #2
0
 public void AfterStarted()
 {
     directObjRefDirectMember = MemberTypeProvider.GetMember(typeof(DirectObjRef), "Direct");
 }
        public override IClassVisitor Extend(IClassVisitor visitor, IBytecodeBehaviorState state, IList <IBytecodeBehavior> remainingPendingBehaviors, IList <IBytecodeBehavior> cascadePendingBehaviors)
        {
            MemberEnhancementHint memberHint = state.GetContext <MemberEnhancementHint>();

            if (memberHint == null)
            {
                return(visitor);
            }
            RelationMemberEnhancementHint relationMemberHint = state.GetContext <RelationMemberEnhancementHint>();

            String[] memberNameSplit = EmbeddedMember.Split(memberHint.MemberName);
            if (memberNameSplit.Length == 1)
            {
                IPropertyInfo[] sPropertyPath = new IPropertyInfo[1];
                sPropertyPath[0] = PropertyInfoProvider.GetProperty(memberHint.DeclaringType, memberHint.MemberName);
                visitor          = new EntityMetaDataMemberVisitor(visitor, memberHint.DeclaringType, memberHint.DeclaringType, memberHint.MemberName,
                                                                   EntityMetaDataProvider, sPropertyPath);
                if (relationMemberHint != null)
                {
                    visitor = new EntityMetaDataRelationMemberVisitor(visitor, memberHint.DeclaringType, memberHint.MemberName, sPropertyPath);
                }
                else
                {
                    visitor = new EntityMetaDataPrimitiveMemberVisitor(visitor, memberHint.DeclaringType, memberHint.MemberName, sPropertyPath);
                }
                return(visitor);
            }
            Member[] members  = new Member[memberNameSplit.Length];
            Type     currType = memberHint.DeclaringType;

            IPropertyInfo[] propertyPath = new IPropertyInfo[members.Length];
            StringBuilder   sb           = new StringBuilder();

            for (int a = 0, size = memberNameSplit.Length; a < size; a++)
            {
                if (a + 1 < memberNameSplit.Length)
                {
                    members[a] = MemberTypeProvider.GetMember(currType, memberNameSplit[a]);
                }
                else if (relationMemberHint != null)
                {
                    members[a] = MemberTypeProvider.GetRelationMember(currType, memberNameSplit[a]);
                }
                else
                {
                    members[a] = MemberTypeProvider.GetPrimitiveMember(currType, memberNameSplit[a]);
                }
                if (a > 0)
                {
                    sb.Append('.');
                }
                sb.Append(members[a].Name);
                propertyPath[a] = PropertyInfoProvider.GetProperty(currType, memberNameSplit[a]);
                if (a + 1 < memberNameSplit.Length)
                {
                    currType = BytecodeEnhancer.GetEnhancedType(members[a].RealType,
                                                                new EmbeddedEnhancementHint(memberHint.DeclaringType, currType, sb.ToString()));
                }
                else
                {
                    currType = members[a].RealType;
                }
            }
            visitor = new EntityMetaDataMemberVisitor(visitor, memberHint.DeclaringType, memberHint.DeclaringType, memberHint.MemberName,
                                                      EntityMetaDataProvider, propertyPath);
            if (relationMemberHint != null)
            {
                visitor = new EntityMetaDataRelationMemberVisitor(visitor, memberHint.DeclaringType, memberHint.MemberName, propertyPath);
            }
            else
            {
                visitor = new EntityMetaDataPrimitiveMemberVisitor(visitor, memberHint.DeclaringType, memberHint.MemberName, propertyPath);
            }
            visitor = new EntityMetaDataEmbeddedMemberVisitor(visitor, memberHint.DeclaringType, memberHint.MemberName, members);
            return(visitor);
        }