protected Member RefreshMember(IEntityMetaData metaData, Member member) { if (member == null) { return(null); } if (member is RelationMember) { return(MemberTypeProvider.GetRelationMember(metaData.EnhancedType, member.Name)); } PrimitiveMember refreshedMember = MemberTypeProvider.GetPrimitiveMember(metaData.EnhancedType, member.Name); ((IPrimitiveMemberWrite)refreshedMember).SetTechnicalMember(((PrimitiveMember)member).TechnicalMember); ((IPrimitiveMemberWrite)refreshedMember).SetTransient(((PrimitiveMember)member).Transient); return(refreshedMember); }
public void AfterStarted() { directObjRefDirectMember = MemberTypeProvider.GetMember(typeof(DirectObjRef), "Direct"); }
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); }
public IList <IEntityMetaData> GetMetaData(IList <Type> entityTypes) { List <IEntityMetaData> result = new List <IEntityMetaData>(); for (int a = entityTypes.Count; a-- > 0;) { Type entityType = entityTypes[a]; List <Type> typesRelatingToThis = new List <Type>(); IList <String> primitiveMemberNames = new List <String>(); IList <String> relationMemberNames = new List <String>(); FillMetaData(entityType, typesRelatingToThis, primitiveMemberNames, relationMemberNames); List <PrimitiveMember> primitiveMembers = new List <PrimitiveMember>(); foreach (String primitiveMemberName in primitiveMemberNames) { PrimitiveMember primitiveMember = MemberTypeProvider.GetPrimitiveMember(entityType, primitiveMemberName); if (primitiveMember == null) { throw new Exception("No member with name '" + primitiveMemberName + "' found on entity type '" + entityType.FullName + "'"); } primitiveMembers.Add(primitiveMember); } List <RelationMember> relationMembers = new List <RelationMember>(); foreach (String relationMemberName in relationMemberNames) { RelationMember relationMember = MemberTypeProvider.GetRelationMember(entityType, relationMemberName); if (relationMember == null) { throw new Exception("No member with name '" + relationMemberName + "' found on entity type '" + entityType.FullName + "'"); } relationMembers.Add(relationMember); } EntityMetaData emd = new EntityMetaData(); emd.EntityType = entityType; emd.IdMember = MemberTypeProvider.GetPrimitiveMember(entityType, "Id"); emd.VersionMember = MemberTypeProvider.GetPrimitiveMember(entityType, "Version"); emd.UpdatedByMember = MemberTypeProvider.GetPrimitiveMember(entityType, "UpdatedBy"); emd.UpdatedOnMember = MemberTypeProvider.GetPrimitiveMember(entityType, "UpdatedOn"); emd.CreatedByMember = MemberTypeProvider.GetPrimitiveMember(entityType, "CreatedBy"); emd.CreatedOnMember = MemberTypeProvider.GetPrimitiveMember(entityType, "CreatedOn"); if (emd.UpdatedByMember != null) { primitiveMembers.Add(emd.UpdatedByMember); } if (emd.UpdatedOnMember != null) { primitiveMembers.Add(emd.UpdatedOnMember); } if (emd.CreatedByMember != null) { primitiveMembers.Add(emd.CreatedByMember); } if (emd.CreatedOnMember != null) { primitiveMembers.Add(emd.CreatedOnMember); } emd.PrimitiveMembers = primitiveMembers.ToArray(); emd.RelationMembers = relationMembers.ToArray(); emd.TypesRelatingToThis = typesRelatingToThis.ToArray(); emd.Initialize(CacheModification, EntityFactory); result.Add(emd); } return(result); }
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); }