private void addBidirectionalInfo(IDictionary <System.Type, IEntityMeta> metas) { foreach (var type in metas.Keys) { var persistentClass = _nhibernateConfiguration.GetClassMapping(type); if (persistentClass == null) { continue; } foreach (var property in persistentClass.PropertyIterator) { //is it a collection? var collectionValue = property.Value as Mapping.Collection; if (collectionValue == null) { continue; } //find referenced entity name var referencedEntity = MappingTools.ReferencedEntityName(property.Value); if (referencedEntity == null) { continue; } var refPersistentClass = _nhibernateConfiguration.GetClassMapping(referencedEntity); foreach (var refProperty in refPersistentClass.PropertyClosureIterator) { if (MetadataTools.IsNoneAccess(refProperty.PropertyAccessorName)) { continue; } var attr = createAuditMappedByAttributeIfReferenceImmutable(collectionValue, refProperty); if (attr == null) { continue; } mightAddIndexToAttribute(attr, collectionValue, refPersistentClass.PropertyClosureIterator); var entityMeta = (EntityMeta)metas[type]; var methodInfo = PropertyAndMemberInfo.PersistentInfo(type, new[] { property }).First().Member; addToEntityMeta(attr, entityMeta, methodInfo); } } } }
public static IEnumerable <DeclaredPersistentProperty> PersistentInfo(System.Type @class, IEnumerable <Property> properties, bool includeEmbedded) { // a persistent property can be anything including a noop "property" declared in the mapping // for query only. In this case I will apply some trick to get the MemberInfo. var candidateMembers = @class.GetFields(DefaultBindingFlags).Concat(@class.GetProperties(DefaultBindingFlags).Cast <MemberInfo>()).ToList(); var candidateMembersNames = candidateMembers.Select(m => m.Name).ToList(); foreach (var property in properties) { if (includeEmbedded && property.PropertyAccessorName == "embedded") { yield return(new DeclaredPersistentProperty(property, DeclaredPersistentProperty.NotAvailableMemberInfo)); } if (MetadataTools.IsNoneAccess(property.PropertyAccessorName)) { yield return(new DeclaredPersistentProperty(property, DeclaredPersistentProperty.NotAvailableMemberInfo)); } var exactMemberIdx = candidateMembersNames.IndexOf(property.Name); if (exactMemberIdx >= 0) { // No metter which is the accessor the audit-attribute should be in the property where available and not // to the member used to read-write the value. (This method work even for access="field"). yield return(new DeclaredPersistentProperty(property, candidateMembers[exactMemberIdx])); } else { // try to find the field using field-name-strategy // // This part will run for: // 1) query only property (access="none" or access="noop") // 2) a strange case where the element <property> is declared with a "field.xyz" but only a field is used in the class. (Only God may know way) var exactFieldIdx = getMemberIdxByFieldNamingStrategies(candidateMembersNames, property); if (exactFieldIdx >= 0) { yield return(new DeclaredPersistentProperty(property, candidateMembers[exactFieldIdx])); } } } }