protected void WriteObjRefs(IObjRef[] objRefs, IWriter writer, IncrementalMergeState incrementalState) { IConversionHelper conversionHelper = ConversionHelper; IObjRef[] clone = (IObjRef[])objRefs.Clone(); Array.Sort(clone, incrementalState.objRefComparator); foreach (IObjRef item in clone) { writer.WriteStartElement("Entity"); StateEntry stateEntry = incrementalState.objRefToStateMap.Get(item); if (stateEntry != null) { writer.WriteAttribute("idx", stateEntry.index); writer.WriteEndElement(); continue; } IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(item.RealType); writer.WriteAttribute("type", metaData.EntityType.FullName); PrimitiveMember idMember = metaData.GetIdMemberByIdIndex(item.IdNameIndex); writer.WriteAttribute(idMember.Name, conversionHelper.ConvertValueToType <String>(item.Id)); if (item.Version != null) { writer.WriteAttribute("version", conversionHelper.ConvertValueToType <String>(item.Version)); } writer.WriteEndElement(); } }
protected PrimitiveMember GetIfExists(PrimitiveMember memberToRefresh, IMap <String, PrimitiveMember> nameToPrimitiveMember) { if (memberToRefresh == null) { return(null); } return(nameToPrimitiveMember.Get(memberToRefresh.Name)); }
protected void SetTechnicalMember(PrimitiveMember member) { if (member == null) { return; } ((IPrimitiveMemberWrite)member).SetTechnicalMember(true); }
protected override Object GetVersionOfCacheValue(IEntityMetaData metaData, Object cacheValue) { PrimitiveMember versionMember = metaData.VersionMember; if (versionMember == null) { return(null); } return(versionMember.GetValue(cacheValue, false)); }
public void ChangeInterningBehavior(PrimitiveMember primitiveMember, bool state) { if (state) { interningMemberSet.Add(primitiveMember); } else { interningMemberSet.Remove(primitiveMember); } }
protected override void SetVersionOfCacheValue(IEntityMetaData metaData, Object cacheValue, Object version) { PrimitiveMember versionMember = metaData.VersionMember; if (versionMember == null) { return; } version = ConversionHelper.ConvertValueToType(versionMember.RealType, version); versionMember.SetValue(cacheValue, version); }
protected PrimitiveMember GetPrimitiveMember(Type entityType, IPropertyInfo property, IMap <String, Member> nameToMemberMap) { PrimitiveMember member = (PrimitiveMember)nameToMemberMap.Get(property.Name); if (member != null) { return(member); } member = IntermediateMemberTypeProvider.GetIntermediatePrimitiveMember(entityType, property.Name); nameToMemberMap.Put(property.Name, member); return(member); }
public void RefreshMembers(IEntityMetaData metaData) { if (metaData.EnhancedType == null) { ((EntityMetaData)metaData).Initialize(CacheModification, EntityFactory); IEntityInstantiationExtension eie = entityInstantiationExtensions.GetExtension(metaData.EntityType); Type baseType = eie != null?eie.GetMappedEntityType(metaData.EntityType) : metaData.EntityType; ((EntityMetaData)metaData).EnhancedType = BytecodeEnhancer.GetEnhancedType(baseType, EntityEnhancementHint.Instance); } RelationMember[] relationMembers = metaData.RelationMembers; for (int a = relationMembers.Length; a-- > 0;) { relationMembers[a] = (RelationMember)RefreshMember(metaData, relationMembers[a]); } PrimitiveMember[] primitiveMembers = metaData.PrimitiveMembers; for (int a = primitiveMembers.Length; a-- > 0;) { primitiveMembers[a] = (PrimitiveMember)RefreshMember(metaData, primitiveMembers[a]); } HashMap <String, PrimitiveMember> nameToPrimitiveMember = new HashMap <String, PrimitiveMember>(); for (int a = primitiveMembers.Length; a-- > 0;) { PrimitiveMember member = primitiveMembers[a]; nameToPrimitiveMember.Put(member.Name, member); } PrimitiveMember[] alternateIdMembers = metaData.AlternateIdMembers; for (int a = alternateIdMembers.Length; a-- > 0;) { alternateIdMembers[a] = (PrimitiveMember)RefreshMember(metaData, alternateIdMembers[a]); } ((EntityMetaData)metaData).IdMember = RefreshDefinedBy((PrimitiveMember)RefreshMember(metaData, metaData.IdMember), nameToPrimitiveMember); ((EntityMetaData)metaData).VersionMember = RefreshDefinedBy((PrimitiveMember)RefreshMember(metaData, metaData.VersionMember), nameToPrimitiveMember); ((EntityMetaData)metaData).UpdatedByMember = GetIfExists(metaData.UpdatedByMember, nameToPrimitiveMember); ((EntityMetaData)metaData).UpdatedOnMember = GetIfExists(metaData.UpdatedOnMember, nameToPrimitiveMember); ((EntityMetaData)metaData).CreatedByMember = GetIfExists(metaData.CreatedByMember, nameToPrimitiveMember); ((EntityMetaData)metaData).CreatedOnMember = GetIfExists(metaData.CreatedOnMember, nameToPrimitiveMember); for (int a = primitiveMembers.Length; a-- > 0;) { RefreshDefinedBy(primitiveMembers[a], nameToPrimitiveMember); } for (int a = alternateIdMembers.Length; a-- > 0;) { RefreshDefinedBy(alternateIdMembers[a], nameToPrimitiveMember); } UpdateEntityMetaDataWithLifecycleExtensions(metaData); ((EntityMetaData)metaData).Initialize(CacheModification, EntityFactory); }
protected PrimitiveMember[] GetPrimitiveMembers(Type entityType, String[] memberNames, IMap <String, Member> nameToMemberDict) { if (memberNames == null) { return(EntityMetaData.EmptyPrimitiveMembers); } PrimitiveMember[] members = new PrimitiveMember[memberNames.Length]; for (int a = memberNames.Length; a-- > 0;) { members[a] = GetPrimitiveMember(entityType, memberNames[a], nameToMemberDict); } return(members); }
protected virtual bool EqualsReferenceOrId(Object original, Object clone, MergeHandle handle, IEntityMetaData metaData) { if (original == null) { return(clone == null); } if (clone == null) { return(false); } PrimitiveMember keyMember = metaData.IdMember; return(Object.Equals(keyMember.GetValue(clone, true), keyMember.GetValue(original, true))); }
public void TestPrimitiveMember() { var obj = new PrimitiveMember { Member = 5 }; var container = new NodeContainer(); var node = (GraphNode)container.GetOrCreateNode(obj); Assert.AreEqual(obj, node.Content.Value); Assert.AreEqual(1, node.Children.Count); Assert.AreEqual(nameof(PrimitiveMember.Member), node.Children.First().Name); Assert.AreEqual(obj.Member, node.Children.First().Content.Value); obj.Member = 6; Assert.AreEqual(obj.Member, node.Children.First().Content.Value); node.Children.First().Content.Update(7); Assert.AreEqual(obj.Member, node.Children.First().Content.Value); }
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 CompositeIdMember(Type declaringType, Type realType, String name, PrimitiveMember[] members, IMemberTypeProvider memberTypeProvider) { this.declaringType = declaringType; this.realType = realType; this.name = name; this.members = members; fieldIndexOfMembers = new PrimitiveMember[members.Length]; Type[] paramTypes = new Type[members.Length]; for (int a = 0, size = members.Length; a < size; a++) { PrimitiveMember member = members[a]; fieldIndexOfMembers[a] = memberTypeProvider.GetMember(realType, CompositeIdMember.FilterEmbeddedFieldName(member.Name)); paramTypes[a] = member.RealType; } realTypeConstructorAccess = realType.GetConstructor(paramTypes); }
protected PrimitiveMember HandleMemberConfigIfNew(Type entityType, String memberName, IMap <String, Member> memberConfigToInfoItem) { PrimitiveMember member = (PrimitiveMember)memberConfigToInfoItem.Get(memberName); if (member != null) { return(member); } member = IntermediateMemberTypeProvider.GetIntermediatePrimitiveMember(entityType, memberName); if (member == null) { throw new Exception("No member with name '" + memberName + "' found on entity type '" + entityType.Name + "'"); } memberConfigToInfoItem.Put(memberName, member); return(member); }
public virtual Object ReadObject(Type returnType, String elementName, int id, IReader reader) { if (!XmlDictionary.EntityRefElement.Equals(elementName)) { throw new Exception("Element '" + elementName + "' not supported"); } String idIndexValue = reader.GetAttributeValue(idNameIndex); sbyte idIndex = idIndexValue != null?SByte.Parse(idIndexValue) : ObjRef.PRIMARY_KEY_INDEX; reader.NextTag(); Type realType = (Type)reader.ReadObject(); Object objId = reader.ReadObject(); Object version = reader.ReadObject(); if (objId != null || version != null) { IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(realType, true); if (metaData != null) { if (objId != null) { PrimitiveMember idMember = metaData.GetIdMemberByIdIndex(idIndex); if (objId.Equals(idMember.NullEquivalentValue)) { objId = null; } } if (version != null) { PrimitiveMember versionMember = metaData.VersionMember; if (versionMember != null) { if (version.Equals(versionMember.NullEquivalentValue)) { version = null; } } } } } IObjRef obj = ObjRefFactory.CreateObjRef(realType, idIndex, objId, version); return(obj); }
public Object CreateCompositeId(IEntityMetaData metaData, PrimitiveMember compositeIdMember, params Object[] ids) { IConversionHelper conversionHelper = this.ConversionHelper; CompositeIdMember cIdTypeInfoItem = (CompositeIdMember)compositeIdMember; PrimitiveMember[] members = cIdTypeInfoItem.Members; for (int a = ids.Length; a-- > 0;) { Object id = ids[a]; Object convertedId = conversionHelper.ConvertValueToType(members[a].RealType, id); if (convertedId != id) { ids[a] = convertedId; } } return(cIdTypeInfoItem.GetRealTypeConstructorAccess().Invoke(ids)); }
public Object CreateIdFromPrimitives(IEntityMetaData metaData, int idIndex, Object[] primitives) { int[][] alternateIdMemberIndicesInPrimitives = metaData.AlternateIdMemberIndicesInPrimitives; int[] compositeIndex = alternateIdMemberIndicesInPrimitives[idIndex]; if (compositeIndex.Length == 1) { return(primitives[compositeIndex[0]]); } PrimitiveMember compositeIdMember = metaData.AlternateIdMembers[idIndex]; Object[] ids = new Object[compositeIndex.Length]; for (int a = compositeIndex.Length; a-- > 0;) { ids[a] = primitives[compositeIndex[a]]; } return(CreateCompositeId(metaData, compositeIdMember, ids)); }
public void TestPrimitiveMember() { var obj = new PrimitiveMember { Member = 5 }; var container = new NodeContainer(); var node = (GraphNode)container.GetOrCreateNode(obj); Assert.AreEqual(obj, node.Content.Value); Assert.AreEqual(1, node.Children.Count); Assert.AreEqual(nameof(PrimitiveMember.Member), node.Children.First().Name); Assert.AreEqual(obj.Member, node.Children.First().Content.Value); obj.Member = 6; Assert.AreEqual(obj.Member, node.Children.First().Content.Value); node.Children.First().Content.Update(7); Assert.AreEqual(obj.Member, node.Children.First().Content.Value); }
protected PrimitiveMember RefreshDefinedBy(PrimitiveMember member, IMap <String, PrimitiveMember> nameToPrimitiveMember) { if (member == null) { return(member); } PrimitiveMember definedBy = member.DefinedBy; if (definedBy == null) { return(member); } PrimitiveMember refreshedDefinedBy = nameToPrimitiveMember.Get(definedBy.Name); if (refreshedDefinedBy == null) { throw new Exception("Must never happen"); } ((IPrimitiveMemberWrite)member).SetDefinedBy(refreshedDefinedBy); return(member); }
protected PrimitiveMember HandleMemberConfig(IEntityMetaData metaData, Type realType, IMemberConfig memberConfig, IMap <String, Member> explicitMemberNameToMember, IMap <String, Member> allMemberNameToMember) { if (memberConfig == null) { return(null); } if (!(memberConfig is CompositeMemberConfig)) { PrimitiveMember member = HandleMemberConfigIfNew(realType, memberConfig.Name, explicitMemberNameToMember); explicitMemberNameToMember.Put(memberConfig.Name, member); ((IPrimitiveMemberWrite)member).SetTransient(memberConfig.Transient); PrimitiveMember definedBy = memberConfig.DefinedBy != null?HandleMemberConfigIfNew(realType, memberConfig.DefinedBy, allMemberNameToMember) : null; ((IPrimitiveMemberWrite)member).SetDefinedBy(definedBy); return(member); } MemberConfig[] memberConfigs = ((CompositeMemberConfig)memberConfig).GetMembers(); PrimitiveMember[] members = new PrimitiveMember[memberConfigs.Length]; for (int a = memberConfigs.Length; a-- > 0;) { MemberConfig memberPart = memberConfigs[a]; PrimitiveMember member = HandleMemberConfigIfNew(realType, memberPart.Name, explicitMemberNameToMember); members[a] = member; } PrimitiveMember compositeIdMember = CompositeIdFactory.CreateCompositeIdMember(metaData, members); explicitMemberNameToMember.Put(memberConfig.Name, compositeIdMember); ((IPrimitiveMemberWrite)compositeIdMember).SetTransient(memberConfig.Transient); PrimitiveMember definedBy2 = memberConfig.DefinedBy != null?HandleMemberConfigIfNew(realType, memberConfig.DefinedBy, allMemberNameToMember) : null; ((IPrimitiveMemberWrite)compositeIdMember).SetDefinedBy(definedBy2); return(compositeIdMember); }
public Object[] ExtractPrimitives(IEntityMetaData metaData, Object obj) { PrimitiveMember[] primitiveMembers = metaData.PrimitiveMembers; Object[] primitives; if (primitiveMembers.Length == 0) { primitives = emptyObjectArray; } else { primitives = new Object[primitiveMembers.Length]; for (int a = primitiveMembers.Length; a-- > 0;) { PrimitiveMember primitiveMember = primitiveMembers[a]; Object primitiveValue = primitiveMember.GetValue(obj, true); primitives[a] = primitiveValue; } } return(primitives); }
public virtual void DataChanged(IDataChange dataChange, DateTime dispatchTime, long sequenceId) { dataChange = dataChange.Derive(InterestedEntityTypes); if (dataChange.IsEmpty) { return; } ISet <Object> directObjectsToDelete = null; ISet <Type> requestedTypes = new HashSet <Type>(); IDictionary <Type, IEntityMetaData> typeToMetaDataDict = new Dictionary <Type, IEntityMetaData>(); GuiThreadHelper.InvokeInGuiAndWait(delegate() { IList <T> entities = Model.Objects; for (int i = entities.Count; i-- > 0;) { Object entity = entities[i]; requestedTypes.Add(entity.GetType()); } }); IList <IDataChangeEntry> dataChangeEntries = dataChange.Inserts; for (int a = dataChangeEntries.Count; a-- > 0;) { requestedTypes.Add(dataChangeEntries[a].EntityType); } dataChangeEntries = dataChange.Updates; for (int a = dataChangeEntries.Count; a-- > 0;) { requestedTypes.Add(dataChangeEntries[a].EntityType); } dataChangeEntries = dataChange.Deletes; for (int a = dataChangeEntries.Count; a-- > 0;) { requestedTypes.Add(dataChangeEntries[a].EntityType); } IList <IEntityMetaData> metaDatas = EntityMetaDataProvider.GetMetaData(ListUtil.ToList(requestedTypes)); foreach (IEntityMetaData metaData in metaDatas) { typeToMetaDataDict[metaData.EntityType] = metaData; } bool consistsOnlyOfDirectDeletes = false; if (dataChange.Deletes.Count > 0) { consistsOnlyOfDirectDeletes = true; foreach (IDataChangeEntry deleteEntry in dataChange.Deletes) { if (deleteEntry is DirectDataChangeEntry) { if (directObjectsToDelete == null) { directObjectsToDelete = new IdentityHashSet <Object>(); } directObjectsToDelete.Add(((DirectDataChangeEntry)deleteEntry).Entry); } else { consistsOnlyOfDirectDeletes = false; } } } IList <T> interestingEntities = null; Object[] contextInformation = GetContextInformation(); IFilterDescriptor filterDescriptor = GetFilterDescriptor(); IList <ISortDescriptor> sortDescriptors = GetSortDescriptors(); IPagingRequest pagingRequest = GetPagingRequest(); IPagingResponse pagingResponse = null; List <IDataChangeEntry> modifiedEntries = new List <IDataChangeEntry>(); modifiedEntries.AddRange(dataChange.All); if (!consistsOnlyOfDirectDeletes) { interestingEntities = CacheContext.ExecuteWithCache(CacheProvider.GetCurrentCache(), delegate() { ConfigureCacheWithEagerLoads(Cache); if (Refresher is IPagingRefresher <T> ) { interestingEntities = new List <T>(); pagingResponse = ((IPagingRefresher <T>)Refresher).Refresh(modifiedEntries, filterDescriptor, sortDescriptors, pagingRequest, contextInformation); foreach (Object obj in pagingResponse.Result) { interestingEntities.Add((T)obj); } return(interestingEntities); } else { if (filterDescriptor != null || sortDescriptors != null) { contextInformation = new Object[2]; contextInformation[0] = filterDescriptor; contextInformation[1] = sortDescriptors; } return(((IRefresher <T>)Refresher).Refresh(modifiedEntries, contextInformation)); } }); } GuiThreadHelper.InvokeInGuiAndWait(delegate() { IList <T> entities = Model.Objects; ISet <T> entitiesToAdd = null; ISet <T> entitiesToRemove = null; IDictionary <T, T> entitiesToReplace = null; IDictionary <IObjRef, T> oldObjRefToOldEntityMap = null; bool mergeModel = false; if (interestingEntities != null && interestingEntities.Count > 0) { entitiesToAdd = new IdentityHashSet <T>(interestingEntities); entitiesToRemove = new IdentityHashSet <T>(entities); entitiesToReplace = new IdentityDictionary <T, T>(); oldObjRefToOldEntityMap = new Dictionary <IObjRef, T>(); mergeModel = true; } for (int i = entities.Count; i-- > 0;) { T oldEntity = entities[i]; if (directObjectsToDelete != null && directObjectsToDelete.Contains(oldEntity)) { if (entitiesToRemove != null) { entitiesToRemove.Remove(oldEntity); } Model.RemoveAt(i); continue; } Type oldEntityType = ProxyHelper.GetRealType(oldEntity.GetType()); PrimitiveMember idMember = typeToMetaDataDict[oldEntityType].IdMember; Object oldEntityId = idMember.GetValue(oldEntity, false); if (oldEntityId == null) { if (entitiesToRemove != null) { entitiesToRemove.Remove(oldEntity); } // Unpersisted object. This object should not be removed // only because of a background DCE continue; } bool entryRemoved = false; foreach (IDataChangeEntry deleteEntry in dataChange.Deletes) { if (deleteEntry is DirectDataChangeEntry) { continue; } Object id = deleteEntry.Id; if (!EqualsItems(oldEntityType, oldEntityId, deleteEntry.EntityType, id)) { continue; } if (entitiesToRemove != null) { entitiesToRemove.Remove(oldEntity); } Model.RemoveAt(i); entryRemoved = true; break; } if (entryRemoved) { continue; } if (mergeModel) { IObjRef oldObjRef = new ObjRef(oldEntityType, ObjRef.PRIMARY_KEY_INDEX, oldEntityId, null); T existingOldEntity = DictionaryExtension.ValueOrDefault(oldObjRefToOldEntityMap, oldObjRef); if (existingOldEntity == null) { oldObjRefToOldEntityMap.Add(oldObjRef, oldEntity); } else if (!Object.ReferenceEquals(existingOldEntity, oldEntity)) { // Force duplicate key exception oldObjRefToOldEntityMap.Add(oldObjRef, oldEntity); } } } if (oldObjRefToOldEntityMap != null && oldObjRefToOldEntityMap.Count > 0) { IDictionary <IObjRef, T> newObjRefToNewEntityMap = new Dictionary <IObjRef, T>(); for (int a = interestingEntities.Count; a-- > 0;) { T newEntity = interestingEntities[a]; Type newEntityType = ProxyHelper.GetRealType(newEntity.GetType()); PrimitiveMember idMember = typeToMetaDataDict[newEntityType].IdMember; Object newEntityId = idMember.GetValue(newEntity, false); IObjRef newObjRef = new ObjRef(newEntityType, ObjRef.PRIMARY_KEY_INDEX, newEntityId, null); newObjRefToNewEntityMap.Add(newObjRef, newEntity); } DictionaryExtension.Loop(oldObjRefToOldEntityMap, delegate(IObjRef objRef, T oldEntity) { T newEntity = DictionaryExtension.ValueOrDefault(newObjRefToNewEntityMap, objRef); if (newEntity == null) { // Nothing to do if current oldEntity has no corresponding newEntity return; } entitiesToAdd.Remove(newEntity); if (!Object.ReferenceEquals(oldEntity, newEntity) && (dataChange.IsLocalSource || !(oldEntity is IDataObject) || !((IDataObject)oldEntity).ToBeUpdated)) { entitiesToReplace[oldEntity] = newEntity; } entitiesToRemove.Remove(oldEntity); }); } if (mergeModel) { for (int a = entities.Count; a-- > 0;) { T item = entities[a]; if (entitiesToRemove.Contains(item)) { Model.RemoveAt(a); continue; } T replacingItem = DictionaryExtension.ValueOrDefault(entitiesToReplace, item); if (replacingItem != null) { Model.Replace(a, replacingItem); continue; } } IEnumerator <T> enumerator = entitiesToAdd.GetEnumerator(); while (enumerator.MoveNext()) { T entityToAdd = enumerator.Current; Model.Add(entityToAdd); } if (hasPagedViewModel) { UpdatePagingInformation(pagingResponse); } UpdateAfterDCE(); } }); }
public Object ConvertValueToType(Type expectedType, Type sourceType, Object value, Object additionalInformation) { if (sourceType.IsAssignableFrom(typeof(EntityMetaData))) { EntityMetaData source = (EntityMetaData)value; EntityMetaDataTransfer target = new EntityMetaDataTransfer(); target.EntityType = source.EntityType; target.IdMemberName = GetNameOfMember(source.IdMember); target.VersionMemberName = GetNameOfMember(source.VersionMember); target.CreatedByMemberName = GetNameOfMember(source.CreatedByMember); target.CreatedOnMemberName = GetNameOfMember(source.CreatedOnMember); target.UpdatedByMemberName = GetNameOfMember(source.UpdatedByMember); target.UpdatedOnMemberName = GetNameOfMember(source.UpdatedOnMember); target.AlternateIdMemberNames = GetNamesOfMembers(source.AlternateIdMembers); target.PrimitiveMemberNames = GetNamesOfMembers(source.PrimitiveMembers); target.RelationMemberNames = GetNamesOfMembers(source.RelationMembers); target.AlternateIdMemberIndicesInPrimitives = source.AlternateIdMemberIndicesInPrimitives; target.TypesRelatingToThis = source.TypesRelatingToThis; target.TypesToCascadeDelete = ListUtil.ToArray(source.CascadeDeleteTypes); PrimitiveMember[] primitiveMembers = source.PrimitiveMembers; RelationMember[] relationMembers = source.RelationMembers; IList <String> mergeRelevantNames = new List <String>(); for (int a = primitiveMembers.Length; a-- > 0;) { PrimitiveMember member = primitiveMembers[a]; if (source.IsMergeRelevant(member)) { mergeRelevantNames.Add(GetNameOfMember(member)); } } for (int a = relationMembers.Length; a-- > 0;) { RelationMember member = relationMembers[a]; if (source.IsMergeRelevant(member)) { mergeRelevantNames.Add(GetNameOfMember(member)); } } target.MergeRelevantNames = ListUtil.ToArray <String>(mergeRelevantNames); return(target); } else if (sourceType.IsAssignableFrom(typeof(EntityMetaDataTransfer))) { EntityMetaDataTransfer source = (EntityMetaDataTransfer)value; HashMap <String, Member> nameToMemberDict = new HashMap <String, Member>(); EntityMetaData target = new EntityMetaData(); Type entityType = source.EntityType; Type realType = ProxyHelper.GetRealType(entityType); target.EntityType = entityType; target.RealType = realType; target.IdMember = GetPrimitiveMember(entityType, source.IdMemberName, nameToMemberDict); target.VersionMember = GetPrimitiveMember(entityType, source.VersionMemberName, nameToMemberDict); target.CreatedByMember = GetPrimitiveMember(entityType, source.CreatedByMemberName, nameToMemberDict); target.CreatedOnMember = GetPrimitiveMember(entityType, source.CreatedOnMemberName, nameToMemberDict); target.UpdatedByMember = GetPrimitiveMember(entityType, source.UpdatedByMemberName, nameToMemberDict); target.UpdatedOnMember = GetPrimitiveMember(entityType, source.UpdatedOnMemberName, nameToMemberDict); target.AlternateIdMembers = GetPrimitiveMembers(entityType, source.AlternateIdMemberNames, nameToMemberDict); target.PrimitiveMembers = GetPrimitiveMembers(entityType, source.PrimitiveMemberNames, nameToMemberDict); target.RelationMembers = GetRelationMembers(entityType, source.RelationMemberNames, nameToMemberDict); target.AlternateIdMemberIndicesInPrimitives = source.AlternateIdMemberIndicesInPrimitives; target.TypesRelatingToThis = source.TypesRelatingToThis; Type[] typesToCascadeDelete = source.TypesToCascadeDelete; for (int a = 0, size = typesToCascadeDelete.Length; a < size; a++) { target.CascadeDeleteTypes.Add(typesToCascadeDelete[a]); } String[] mergeRelevantNames = source.MergeRelevantNames; if (mergeRelevantNames != null) { for (int a = mergeRelevantNames.Length; a-- > 0;) { Member resolvedMember = nameToMemberDict.Get(mergeRelevantNames[a]); target.SetMergeRelevant(resolvedMember, true); } } SetMergeRelevant(target, target.CreatedByMember, false); SetMergeRelevant(target, target.CreatedOnMember, false); SetMergeRelevant(target, target.UpdatedByMember, false); SetMergeRelevant(target, target.UpdatedOnMember, false); SetMergeRelevant(target, target.IdMember, false); SetMergeRelevant(target, target.VersionMember, false); //target.Initialize(CacheModification, EntityFactory); return(target); } throw new Exception("Source of type " + sourceType.Name + " not supported"); }
public void Initialize(ICacheModification cacheModification, IEntityFactory entityFactory) { this.cacheModification = cacheModification; this.entityFactory = entityFactory; if (AlternateIdMemberIndicesInPrimitives == null) { AlternateIdMemberIndicesInPrimitives = EmptyShortArray; } if (PrimitiveMembers == null) { PrimitiveMembers = EmptyPrimitiveMembers; } else { // Array.Sort<INamed>(PrimitiveMembers, namedItemComparer); } List <PrimitiveMember> primitiveToManyMembers = new List <PrimitiveMember>(); foreach (PrimitiveMember primitiveMember in PrimitiveMembers) { if (primitiveMember.IsToMany) { primitiveToManyMembers.Add(primitiveMember); } } this.primitiveToManyMembers = primitiveToManyMembers.ToArray(); if (RelationMembers == null) { RelationMembers = EmptyRelationMembers; } else { // Array.Sort<INamed>(RelationMembers, namedItemComparer); } if (AlternateIdMembers == null) { AlternateIdMembers = EmptyPrimitiveMembers; } else { // Array.Sort<INamed>(AlternateIdMembers, namedItemComparer); } nameToMemberDict.Clear(); relMemberToIndexDict.Clear(); relMemberNameToIndexDict.Clear(); primMemberToIndexDict.Clear(); primMemberNameToIndexDict.Clear(); if (IdMember != null) { PrimitiveMember idMember = IdMember; nameToMemberDict.Add(idMember.Name, idMember); if (idMember is CompositeIdMember) { foreach (PrimitiveMember member in ((CompositeIdMember)idMember).Members) { nameToMemberDict.Add(member.Name, member); } } } if (VersionMember != null) { nameToMemberDict.Add(VersionMember.Name, VersionMember); } for (int a = PrimitiveMembers.Length; a-- > 0;) { Member member = PrimitiveMembers[a]; nameToMemberDict.Add(member.Name, member); primMemberNameToIndexDict.Add(member.Name, a); primMemberToIndexDict.Add(member, a); if (Object.ReferenceEquals(member, IdMember) || Object.ReferenceEquals(member, VersionMember) || Object.ReferenceEquals(member, UpdatedByMember) || Object.ReferenceEquals(member, UpdatedOnMember) || Object.ReferenceEquals(member, CreatedByMember) || Object.ReferenceEquals(member, CreatedOnMember)) { // technical members must never be merge relevant SetMergeRelevant(member, false); } } for (int a = RelationMembers.Length; a-- > 0;) { RelationMember member = RelationMembers[a]; nameToMemberDict.Add(member.Name, member); relMemberNameToIndexDict.Add(member.Name, a); relMemberToIndexDict.Add(member, a); } memberNameToIdIndexDict.Clear(); if (IdMember != null) { memberNameToIdIndexDict.Add(IdMember.Name, ObjRef.PRIMARY_KEY_INDEX); } AlternateIdMemberIndicesInPrimitives = new int[AlternateIdMembers.Length][]; for (int idIndex = AlternateIdMembers.Length; idIndex-- > 0;) { int[] compositeIndex = null; Member alternateIdMember = AlternateIdMembers[idIndex]; Member[] memberItems; if (alternateIdMember is CompositeIdMember) { memberItems = ((CompositeIdMember)alternateIdMember).Members; } else { memberItems = new Member[] { alternateIdMember }; } compositeIndex = new int[memberItems.Length]; for (int compositePosition = compositeIndex.Length; compositePosition-- > 0;) { compositeIndex[compositePosition] = -1; Member memberItem = memberItems[compositePosition]; for (int primitiveIndex = PrimitiveMembers.Length; primitiveIndex-- > 0;) { if (memberItem.Equals(PrimitiveMembers[primitiveIndex])) { compositeIndex[compositePosition] = primitiveIndex; break; } } if (compositeIndex[compositePosition] == -1) { throw new Exception("AlternateId is not a primitive: " + memberItem); } } AlternateIdMemberIndicesInPrimitives[idIndex] = compositeIndex; memberNameToIdIndexDict.Add(alternateIdMember.Name, (sbyte)idIndex); } if (TypesRelatingToThis != null && TypesRelatingToThis.Length > 0) { for (int i = TypesRelatingToThis.Length; i-- > 0;) { typesRelatingToThisSet.Add(TypesRelatingToThis[i]); } } if (CreatedByMember != null) { ChangeInterningBehavior(CreatedByMember, true); } if (UpdatedByMember != null) { ChangeInterningBehavior(UpdatedByMember, true); } SetTechnicalMember(IdMember); SetTechnicalMember(VersionMember); SetTechnicalMember(CreatedByMember); SetTechnicalMember(CreatedOnMember); SetTechnicalMember(UpdatedByMember); SetTechnicalMember(UpdatedOnMember); }
public void SetDefinedBy(PrimitiveMember definedBy) { this.definedBy = definedBy; }
protected bool ArePrimitivesEqual(IEntityMetaData metaData, PrimitiveMember primitiveMember, Object objValue, Object cloneValue, MergeHandle handle) { if (objValue != null && cloneValue != null) { if (objValue is Array && cloneValue is Array) { Array objArray = (Array)objValue; Array cloneArray = (Array)cloneValue; if (objArray.Length != cloneArray.Length) { return(false); } for (int b = objArray.Length; b-- > 0;) { Object objItem = objArray.GetValue(b); Object cloneItem = cloneArray.GetValue(b); if (!EqualsObjects(objItem, cloneItem)) { return(false); } } return(true); } else if (objValue is IList && cloneValue is IList) { IList objList = (IList)objValue; IList cloneList = (IList)cloneValue; if (objList.Count != cloneList.Count) { return(false); } for (int b = objList.Count; b-- > 0;) { Object objItem = objList[b]; Object cloneItem = cloneList[b]; if (!EqualsObjects(objItem, cloneItem)) { return(false); } } return(true); } else if (TypeInfoProvider.GetTypeInfo(objValue.GetType()).DoesImplement(typeof(ISet <>)) && TypeInfoProvider.GetTypeInfo(cloneValue.GetType()).DoesImplement(typeof(ISet <>))) { if (((ICollection)objValue).Count != ((ICollection)cloneValue).Count) { return(false); } MethodInfo setEqualsMethod = cloneValue.GetType().GetMethod("SetEquals"); return((bool)setEqualsMethod.Invoke(cloneValue, new Object[] { objValue })); } else if (objValue is ICollection && cloneValue is ICollection) { IEnumerator objIter = ((IEnumerable)objValue).GetEnumerator(); IEnumerator cloneIter = ((IEnumerable)cloneValue).GetEnumerator(); while (objIter.MoveNext()) { if (!cloneIter.MoveNext()) { return(false); } Object objItem = objIter.Current; Object cloneItem = cloneIter.Current; if (!EqualsObjects(objItem, cloneItem)) { return(false); } } if (cloneIter.MoveNext()) { return(false); } return(true); } else if (objValue is IEnumerable && cloneValue is IEnumerable) { IEnumerator objIter = ((IEnumerable)objValue).GetEnumerator(); IEnumerator cloneIter = ((IEnumerable)cloneValue).GetEnumerator(); while (objIter.MoveNext()) { if (!cloneIter.MoveNext()) { return(false); } Object objItem = objIter.Current; Object cloneItem = cloneIter.Current; if (!EqualsObjects(objItem, cloneItem)) { return(false); } } if (cloneIter.MoveNext()) { return(false); } return(true); } } return(EqualsObjects(objValue, cloneValue)); }
protected virtual void Merge(Object obj, Object clone, MergeHandle handle) { IEntityMetaDataProvider entityMetaDataProvider = this.EntityMetaDataProvider; IEntityMetaData metaData = ((IEntityMetaDataHolder)obj).Get__EntityMetaData(); bool fieldBasedMergeActive = handle.FieldBasedMergeActive; bool oneChangeOccured = false; try { RelationMember[] relationMembers = metaData.RelationMembers; if (relationMembers.Length > 0) { IObjRefContainer vhc = (IObjRefContainer)obj; for (int relationIndex = relationMembers.Length; relationIndex-- > 0;) { RelationMember relationMember = relationMembers[relationIndex]; if (!metaData.IsMergeRelevant(relationMember)) { continue; } if (ValueHolderState.INIT != vhc.Get__State(relationIndex)) { // v2 valueholder is not initialized. so a change is impossible continue; } Object objMember = relationMember.GetValue(obj, false); Object cloneMember = relationMember.GetValue(clone, false); if (objMember is IDataObject && !((IDataObject)objMember).HasPendingChanges) { IEntityMetaData relationMetaData = entityMetaDataProvider.GetMetaData(relationMember.RealType); if (EqualsReferenceOrId(objMember, cloneMember, handle, relationMetaData)) { continue; } } IEntityMetaData childMetaData = entityMetaDataProvider.GetMetaData(relationMember.ElementType); if (IsMemberModified(objMember, cloneMember, handle, childMetaData)) { oneChangeOccured = true; AddOriModification(obj, relationMember.Name, objMember, cloneMember, handle); } } } if (fieldBasedMergeActive) { MergePrimitivesFieldBased(metaData, obj, clone, handle); return; } bool additionalRound; do { additionalRound = !oneChangeOccured; foreach (PrimitiveMember primitiveMember in metaData.PrimitiveMembers) { if (!metaData.IsMergeRelevant(primitiveMember)) { continue; } Object objValue = primitiveMember.GetValue(obj, true); if (oneChangeOccured) { AddModification(obj, primitiveMember.Name, primitiveMember.ElementType, objValue, null, handle); continue; } Object cloneValue = primitiveMember.GetValue(clone, true); if (!ArePrimitivesEqual(metaData, primitiveMember, objValue, cloneValue, handle)) { oneChangeOccured = true; break; } } }while (additionalRound && oneChangeOccured); } finally { PrimitiveMember versionMember = metaData.VersionMember; if (oneChangeOccured && versionMember != null) { // Check for early optimistic locking (Another, later level is directly on persistence layer) Object versionToMerge = versionMember.GetValue(obj, true); Object currentVersion = versionMember.GetValue(clone, true); int compareResult = ((IComparable)versionToMerge).CompareTo(currentVersion); if (ExactVersionForOptimisticLockingRequired ? compareResult != 0 : compareResult < 0) { throw new OptimisticLockException(currentVersion, versionToMerge, obj); } } } }
protected void ApplyChangesToOriginalsIntern(ICUDResult cudResult, IOriCollection oriCollection, ICache cache) { ICacheModification cacheModification = this.CacheModification; IConversionHelper conversionHelper = this.ConversionHelper; IEntityMetaDataProvider entityMetaDataProvider = this.EntityMetaDataProvider; IList <Object> originalRefs = cudResult.GetOriginalRefs(); IList <IObjRef> allChangeORIs = oriCollection.AllChangeORIs; String[] allChangedBy = oriCollection.AllChangedBy; long[] allChangedOn = oriCollection.AllChangedOn; String singleChangedBy = oriCollection.ChangedBy; long? singleChangedOn = oriCollection.ChangedOn; bool newInstanceOnCall = CacheProvider.IsNewInstanceOnCall; IList <Object> validObjects = new List <Object>(originalRefs.Count); bool oldCacheModificationValue = CacheModification.Active; CacheModification.Active = true; try { for (int a = originalRefs.Count; a-- > 0;) { Object originalRef = originalRefs[a]; IObjRef ori = allChangeORIs[a]; if (originalRef == null) { // Object has been deleted by cascade delete contraints on server merge or simply a "not specified" original ref continue; } if (originalRef is IObjRef) { continue; } long? changedOn = allChangedOn != null ? allChangedOn[a] : singleChangedOn; String changedBy = allChangedBy != null ? allChangedBy[a] : singleChangedBy; IEntityMetaData metaData = ((IEntityMetaDataHolder)originalRef).Get__EntityMetaData(); PrimitiveMember versionMember = metaData.VersionMember; PrimitiveMember keyMember = metaData.IdMember; PrimitiveMember onMember, byMember; if (keyMember.GetValue(originalRef, false) == null) { onMember = metaData.CreatedOnMember; byMember = metaData.CreatedByMember; } else { onMember = metaData.UpdatedOnMember; byMember = metaData.UpdatedByMember; } if (onMember != null && changedOn != null) { Object createdOn = ConversionHelper.ConvertValueToType(onMember.ElementType, changedOn); onMember.SetValue(originalRef, createdOn); } if (byMember != null && changedBy != null) { Object createdBy = ConversionHelper.ConvertValueToType(byMember.ElementType, changedBy); byMember.SetValue(originalRef, createdBy); } if (ori == null) { keyMember.SetValue(originalRef, null); if (versionMember != null) { versionMember.SetValue(originalRef, null); } if (originalRef is IDataObject) { ((IDataObject)originalRef).ToBeUpdated = false; ((IDataObject)originalRef).ToBeDeleted = false; } continue; // Object has been deleted directly } keyMember.SetValue(originalRef, ConversionHelper.ConvertValueToType(keyMember.RealType, ori.Id)); if (versionMember != null) { if (AlwaysUpdateVersionInChangedEntities) { versionMember.SetValue(originalRef, ConversionHelper.ConvertValueToType(versionMember.RealType, ori.Version)); } else { // We INTENTIONALLY do NOT set the version and let it on its old value, to force the following DCE to refresh the cached object with 'real' data // If we set the version here to the ori.getVersion(), the DCE will 'see' a already valid object - but is IS NOT valid // because it may not contain bi-directional information which can only be resolved by reloading the object from persistence layer //versionMember.SetValue(originalRef, null); } } if (originalRef is IDataObject) { ((IDataObject)originalRef).ToBeUpdated = false; ((IDataObject)originalRef).ToBeDeleted = false; } validObjects.Add(originalRef); } PutInstancesToCurrentCache(validObjects, cache); } finally { CacheModification.Active = oldCacheModificationValue; } }
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 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 void AddMembers(EntityMetaData metaData, IEntityConfig entityConfig) { Type realType = entityConfig.RealType; ISet <String> memberNamesToIgnore = new HashSet <String>(); ISet <String> explicitBasicMemberNames = new HashSet <String>(); IList <IMemberConfig> embeddedMembers = new List <IMemberConfig>(); IMap <String, IMemberConfig> nameToMemberConfig = new HashMap <String, IMemberConfig>(); IMap <String, IRelationConfig> nameToRelationConfig = new HashMap <String, IRelationConfig>(); IdentityLinkedMap <String, Member> nameToMemberMap = new IdentityLinkedMap <String, Member>(); FillNameCollections(entityConfig, memberNamesToIgnore, explicitBasicMemberNames, embeddedMembers, nameToMemberConfig, nameToRelationConfig); IdentityLinkedSet <PrimitiveMember> alternateIdMembers = new IdentityLinkedSet <PrimitiveMember>(); IdentityLinkedSet <PrimitiveMember> primitiveMembers = new IdentityLinkedSet <PrimitiveMember>(); IdentityLinkedSet <RelationMember> relationMembers = new IdentityLinkedSet <RelationMember>(); IdentityLinkedSet <Member> notMergeRelevant = new IdentityLinkedSet <Member>(); IdentityLinkedSet <Member> containedInAlternateIdMember = new IdentityLinkedSet <Member>(); IPropertyInfo[] properties = PropertyInfoProvider.GetProperties(realType); IdentityLinkedMap <String, Member> explicitlyConfiguredMemberNameToMember = new IdentityLinkedMap <String, Member>(); HashMap <String, IOrmConfig> nameToConfigMap = new HashMap <String, IOrmConfig>(); // Resolve members for all explicit configurations - both simple and composite ones, each with embedded // functionality (dot-member-path) foreach (IMemberConfig memberConfig in entityConfig.GetMemberConfigIterable()) { PutNameToConfigMap(memberConfig, nameToConfigMap); if (memberConfig.Ignore) { continue; } HandleMemberConfig(metaData, realType, memberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); } foreach (IRelationConfig relationConfig in entityConfig.GetRelationConfigIterable()) { PutNameToConfigMap(relationConfig, nameToConfigMap); HandleRelationConfig(realType, relationConfig, explicitlyConfiguredMemberNameToMember); } PutNameToConfigMap(entityConfig.IdMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.VersionMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.CreatedByMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.CreatedOnMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.UpdatedByMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.UpdatedOnMemberConfig, nameToConfigMap); metaData.IdMember = HandleMemberConfig(metaData, realType, entityConfig.IdMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.VersionMember = HandleMemberConfig(metaData, realType, entityConfig.VersionMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.CreatedByMember = HandleMemberConfig(metaData, realType, entityConfig.CreatedByMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.CreatedOnMember = HandleMemberConfig(metaData, realType, entityConfig.CreatedOnMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.UpdatedByMember = HandleMemberConfig(metaData, realType, entityConfig.UpdatedByMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.UpdatedOnMember = HandleMemberConfig(metaData, realType, entityConfig.UpdatedOnMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); IdentityHashSet <Member> idMembers = new IdentityHashSet <Member>(); Member idMember = metaData.IdMember; if (idMember is CompositeIdMember) { idMembers.AddAll(((CompositeIdMember)idMember).Members); } else { idMembers.Add(idMember); } // Handle all explicitly configured members foreach (Entry <String, Member> entry in explicitlyConfiguredMemberNameToMember) { String memberName = entry.Key; IOrmConfig ormConfig = nameToConfigMap.Get(memberName); Member member = entry.Value; if (idMembers.Contains(member)) { continue; } if (ormConfig.ExplicitlyNotMergeRelevant) { notMergeRelevant.Add(member); } if (ormConfig is IRelationConfig) { if (!relationMembers.Add((RelationMember)member)) { throw new Exception("Member has been registered as relation multiple times: " + member.Name); } continue; } if (!(ormConfig is IMemberConfig)) { continue; } if (((IMemberConfig)ormConfig).AlternateId) { if (!alternateIdMembers.Add((PrimitiveMember)member)) { throw new Exception("Member has been registered as alternate id multiple times: " + member.Name); } if (member is CompositeIdMember) { Member[] containedMembers = ((CompositeIdMember)member).Members; containedInAlternateIdMember.AddAll(containedMembers); } } if (!(member is CompositeIdMember) && metaData.VersionMember != member) { // Alternate Ids are normally primitives, too. But Composite Alternate Ids not - only their composite // items are primitives primitiveMembers.Add((PrimitiveMember)member); } } IdentityHashSet <String> explicitTypeInfoItems = IdentityHashSet <String> .Create(explicitlyConfiguredMemberNameToMember.Count); foreach (Entry <String, Member> entry in explicitlyConfiguredMemberNameToMember) { Member member = entry.Value; explicitTypeInfoItems.Add(member.Name); if (member is IEmbeddedMember) { explicitTypeInfoItems.Add(((IEmbeddedMember)member).GetMemberPath()[0].Name); } } // Go through the available members to look for potential auto-mapping (simple, no embedded) for (int i = 0; i < properties.Length; i++) { IPropertyInfo property = properties[i]; String memberName = property.Name; if (memberNamesToIgnore.Contains(memberName)) { continue; } if (explicitTypeInfoItems.Contains(memberName)) { // already configured, no auto mapping needed for this member continue; } MethodPropertyInfo mProperty = (MethodPropertyInfo)property; Type elementType = TypeInfoItemUtil.GetElementTypeUsingReflection(mProperty.Getter.ReturnType, null); if ((nameToMemberMap.Get(property.Name) is RelationMember) || RelationProvider.IsEntityType(elementType)) { RelationMember member = GetRelationMember(metaData.EntityType, property, nameToMemberMap); relationMembers.Add(member); continue; } PrimitiveMember member2 = GetPrimitiveMember(metaData.EntityType, property, nameToMemberMap); if (metaData.IdMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_ID)) { metaData.IdMember = member2; continue; } if (idMembers.Contains(member2) && !alternateIdMembers.Contains(member2) && !containedInAlternateIdMember.Contains(member2)) { continue; } if (member2.Equals(metaData.IdMember) || member2.Equals(metaData.VersionMember) || member2.Equals(metaData.CreatedByMember) || member2.Equals(metaData.CreatedOnMember) || member2.Equals(metaData.UpdatedByMember) || member2.Equals(metaData.UpdatedOnMember)) { continue; } if (metaData.VersionMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_VERSION)) { metaData.VersionMember = member2; continue; } if (metaData.CreatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_BY)) { metaData.CreatedByMember = member2; } else if (metaData.CreatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_ON)) { metaData.CreatedOnMember = member2; } else if (metaData.UpdatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_BY)) { metaData.UpdatedByMember = member2; } else if (metaData.UpdatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_ON)) { metaData.UpdatedOnMember = member2; } primitiveMembers.Add(member2); } foreach (PrimitiveMember member in primitiveMembers) { String memberName = member.Name; if (explicitBasicMemberNames.Contains(memberName)) { // Even if the name would match, this member was explicitly configured as "basic" continue; } if (metaData.CreatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_BY)) { metaData.CreatedByMember = member; } else if (metaData.CreatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_ON)) { metaData.CreatedOnMember = member; } else if (metaData.UpdatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_BY)) { metaData.UpdatedByMember = member; } else if (metaData.UpdatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_ON)) { metaData.UpdatedOnMember = member; } } FilterWrongRelationMappings(relationMembers); // Order of setter calls is important PrimitiveMember[] primitives = primitiveMembers.ToArray(); PrimitiveMember[] alternateIds = alternateIdMembers.ToArray(); RelationMember[] relations = relationMembers.ToArray(); Array.Sort(primitives); Array.Sort(alternateIds); Array.Sort(relations); metaData.PrimitiveMembers = primitives; metaData.AlternateIdMembers = alternateIds; metaData.RelationMembers = relations; foreach (Member member in notMergeRelevant) { metaData.SetMergeRelevant(member, false); } if (metaData.IdMember == null) { throw new Exception("No ID member could be resolved for entity of type " + metaData.RealType); } }