internal static property GetProperty(MemberInfo memberInfo, string prefix = "", Func <MemberInfo, bool> notNull = null) { if (memberInfo.IsReadOnlyProperty()) { return(null); } if (memberInfo.DeclaringType.GetSettableFieldsAndProperties().Any(memberInfo.IsBackingFieldFor)) { return(null); } notNull = notNull ?? (mi => !mi.IsNullable()); var returnType = memberInfo.ReturnType(); var type = GetTypeForPropertyRules.Rules.Select(r => r(memberInfo)).FirstOrDefault(t => t != null); if (type == null || type == typeof(void)) { return(null); //not for mapping, this one } var property = new property() { name = memberInfo.Name, access = memberInfo.Access(), notnull = notNull(memberInfo), }; property.column.Add(new column().Setup(memberInfo, columnPrefix: prefix, notnull: property.notnull)); property.type1 = type.AssemblyQualifiedName; UniqueAttribute.SetUniqueProperties(memberInfo, property); //this if statement could be happily replaced by some nifty lookup table or something if (returnType == typeof(DateTimeOffset) || returnType == typeof(DateTimeOffset?)) { property.type1 = "datetimeoffset"; } if (returnType == typeof(DateTime) || returnType == typeof(DateTime?)) { property.type1 = "UtcDateTime"; } if (returnType.IsEnum) { property.type1 = typeof(EnumStringType <>).MakeGenericType(returnType).AssemblyQualifiedName; } // check nullable enum if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Nullable <>) && returnType.GetGenericArguments()[0].IsEnum) { property.type1 = typeof(EnumStringType <>).MakeGenericType(returnType.GetGenericArguments()[0]).AssemblyQualifiedName; } return(property); }
public void Apply(Type type, @class @class, IEnumerable <Type> entityTypes, hibernatemapping hbm) { var entityMembersOnType = type.GetFieldsAndProperties().Where(p => entityTypes.Contains(p.ReturnType())).ToArray(); foreach (var memberInfo in entityMembersOnType) { var prefix = ColumnNamePrefix(memberInfo); var entityClassElement = memberInfo.ReturnType().ClassElement(hbm); var manyToOne = new manytoone() { name = memberInfo.Name.Sanitise(), column = entityClassElement.id.column.Copy() .Each(c => c.SetName(prefix + c.GetName())) .Each(c => c.index = null) .Each(c => c.notnull = !memberInfo.IsNullable()).ToList(), access = memberInfo.Access(), }; manyToOne.foreignkey = "FK_" + @class.table.Trim('[', ']') + "_" + string.Join("_", manyToOne.column.Select(c => c.name.Trim("[]".ToCharArray()))) + "_to_" + memberInfo.ReturnType().Name.Sanitise(); UniqueAttribute.SetUniqueProperties(memberInfo, manyToOne); @class.manytoone.Add(manyToOne); //if there is a manytoone, there is probably a set on the other object... var potentialCorrespondingCollections = memberInfo.ReturnType().GetAllMembers() //... so we get the collections on the other type .Where(p => setTypes.MakeGenericTypes(type).Any(t => t.IsAssignableFrom(p.ReturnType()))); if (potentialCorrespondingCollections.Count() > 1) { var att = memberInfo.GetCustomAttributes(typeof(ManyToOneHintAttribute), false).SingleOrDefault() as ManyToOneHintAttribute; if (att != null) { potentialCorrespondingCollections = potentialCorrespondingCollections.Where(p => p.Name == att.CorrespondingCollectionName); } } if (potentialCorrespondingCollections.Count() > 1) { throw new Exception("Meow! There is more than 1 collection that might be the inverse! You may need to add a ManyToOneHintAttribute so we know which one to use"); } if (potentialCorrespondingCollections.Count() == 1) { var correspondingCollection = potentialCorrespondingCollections.Single(); if (setTypes.MakeGenericTypes(type).Any(t => t.IsAssignableFrom(correspondingCollection.ReturnType()))) { var set = new set() { name = correspondingCollection.Name, access = correspondingCollection.Access(), key = new key() { column1 = manyToOne.column.Single().name, foreignkey = "FK_" + @class.table.Trim('[', ']') + "_" + string.Join("_", manyToOne.column.Select(c => c.name.Trim("[]".ToCharArray()))) + "_to_" + memberInfo.ReturnType().ClassElement(hbm).table, notnull = false // so inverse works!memberInfo.IsNullable(), }, inverse = true, onetomany = new onetomany() { @class = type.AssemblyQualifiedName }, cascade = "all", }; manyToOne.column.Each(c => c.notnull = false).ToArray(); var otherClassMap = memberInfo.ReturnType().ClassElement(hbm); otherClassMap.set.Add(set); } } } }