private void GenerateRelations() { myRelations = new List <FieldInfo>(); AddRelations(this.type); Type t = this.type.BaseType; int persCount = t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length; while (persCount > 0) { if (t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length > 0) { AddRelations(t); } t = t.BaseType; persCount = t.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length; } // Jetzt stehen alle Relations in myRelations if (checkIfMappingsExist && !this.type.IsAbstract) { for (int i = 0; i < myRelations.Count; i++) { if (cl.FindRelation(((FieldInfo)myRelations[i]).Name) == null) { throw new NDOException(8, "Can't find mapping information for relation " + cl.FullName + "." + myRelations[i] + "."); } } } }
/// <summary> /// Hilfsfunktion für MergeMapping /// </summary> /// <param name="c1">Klasse zum Vergleich</param> /// <param name="c2">Klasse zum Vergleich</param> /// <returns></returns> private bool ClassesAreDifferent(Class c1, Class c2) { var c1Fields = c1.Fields.ToList(); var c2Fields = c2.Fields.ToList(); var c1Relations = c1.Relations.ToList(); var c2Relations = c2.Relations.ToList(); if (c1Fields.Count != c2Fields.Count) { return(true); } if (c1Relations.Count != c2Relations.Count) { return(true); } if (c1.AssemblyName != c2.AssemblyName) { return(true); } if (c1.TableName != c2.TableName) { return(true); } if (OidsAreDifferent(c1.Oid, c2.Oid)) { return(true); } foreach (Field f1 in c1Fields) { Field f2 = c2.FindField(f1.Name); if (null == f2) { return(true); } if (FieldsAreDifferent(f1, f2)) { return(true); } } foreach (Relation r1 in c1Relations) { Relation r2 = c1.FindRelation(r1.FieldName); if (null == r2) { return(true); } if (RelationsAreDifferent(r1, r2)) { return(true); } } return(false); }
void IFieldInitializer.InitFields() { bool isEnhancing = ((IEnhancerSupport)Parent.Parent).IsEnhancing; if (!isEnhancing) { GetOrdinal(); } Class relatedClass = this.RelatedClass; Type t = Parent.SystemType; if (t == null) { throw new InternalException(1155, "Relation.InitFields"); } FieldInfo fi = null; while (fi == null && t != typeof(object)) { fi = t.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); if (fi == null) { t = t.BaseType; } } if (fi == null) { throw new NDOException(20, "Can't find field " + Parent.SystemType.Name + "." + FieldName); } FieldType = fi.FieldType; System.Attribute a = System.Attribute.GetCustomAttribute(fi, typeof(NDORelationAttribute), false); NDORelationAttribute ra = (NDORelationAttribute)a; this.composition = ra != null && (ra.Info & RelationInfo.Composite) != 0; if (fi.FieldType == typeof(System.Collections.IList) || fi.FieldType.GetInterface("IList") != null || fi.FieldType.FullName.StartsWith("System.Collections.Generic.IList`1")) { this.multiplicity = RelationMultiplicity.List; } else if (fi.FieldType.GetCustomAttributes(typeof(NDOPersistentAttribute), false).Length > 0) { this.multiplicity = RelationMultiplicity.Element; } else { throw new NDOException(111, "Invalid field type for relation " + t.FullName + "." + FieldName + ": Type = " + fi.FieldType.Name); } // This could be easier, if we hadn't the choice whether to use // polymorphy or not. bool cond1 = this.Multiplicity == RelationMultiplicity.Element && this.ForeignKeyTypeColumnName != null; bool cond2 = this.Multiplicity == RelationMultiplicity.List && this.MappingTable != null && this.MappingTable.ChildForeignKeyTypeColumnName != null; hasSubclasses = (relatedClass.HasSubclasses) && (cond1 || cond2); if (this.multiplicity == RelationMultiplicity.List) { if (ra == null) { throw new NDOException(97, $"Can't determine relation type for relation {Parent.FullName}.{fi.Name}"); } if (ra.RelationType == null && fi.FieldType.IsGenericType) { this.referencedType = fi.FieldType.GetGenericArguments()[0]; } else { this.referencedType = ra.RelationType; } if (referencedType == null) { throw new NDOException(101, "Can't determine referenced type in relation " + this.Parent.FullName + "." + this.fieldName + ". Provide a type parameter for the [NDORelation] attribute."); } } else { this.referencedType = FieldType; } if (HasSubclasses && Multiplicity == RelationMultiplicity.List && MappingTable == null) { //throw new NDOException(21, "Polymorphic 1:n-relation w/o mapping table is not supported"); Debug.WriteLine("NDO Warning: Polymorphic 1:n-relation " + Parent.FullName + "." + this.FieldName + " w/o mapping table"); } this.definingClass = this.Parent; Type bt = this.Parent.SystemType.BaseType; while (typeof(IPersistenceCapable).IsAssignableFrom(bt)) { Class pcl = this.Parent.Parent.FindClass(bt); if (pcl.FindRelation(this.fieldName) != null) { this.definingClass = pcl; } else { break; } bt = bt.BaseType; } // Do not set fkColumn.Size to a value != 0 in during enhancing, // because that value would be hard coded into the mapping file. // Use (!isEnhancing) to make sure, that the code wasn't called from the enhancer. if (this.MappingTable != null) { // r.ForeignKeyColumns points to the own table. if (Parent.Oid.OidColumns.Count != this.foreignKeyColumns.Count) { throw new NDOException(115, "Column count between relation and Oid doesn't match. Type " + Parent.FullName + " has an oid column count of " + Parent.Oid.OidColumns.Count + ". The Relation " + Parent.FullName + "." + this.fieldName + " has a foreign key column count of " + this.foreignKeyColumns.Count + '.'); } int i = 0; new ForeignKeyIterator(this).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastIndex) { OidColumn oidColumn = (OidColumn)Parent.Oid.OidColumns[i]; if (!isEnhancing && fkColumn.Size == 0) { fkColumn.Size = oidColumn.Size; } fkColumn.SystemType = oidColumn.SystemType; i++; } ); // r.MappingTable.ChildForeignKeyColumns points to the table of the related class. if (relatedClass.Oid.OidColumns.Count != this.mappingTable.ChildForeignKeyColumns.Count()) { throw new NDOException(115, "Column count between relation and Oid doesn't match. Type " + relatedClass.FullName + " has an oid column count of " + relatedClass.Oid.OidColumns.Count + ". The Relation " + this.Parent.FullName + "." + this.fieldName + " has a foreign key column count of " + this.mappingTable.ChildForeignKeyColumns.Count() + '.'); } i = 0; new ForeignKeyIterator(this.mappingTable).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastIndex) { OidColumn oidColumn = (OidColumn)relatedClass.Oid.OidColumns[i]; if (!isEnhancing && fkColumn.Size == 0) { fkColumn.Size = oidColumn.Size; } fkColumn.SystemType = oidColumn.SystemType; i++; } ); } else if (this.multiplicity == RelationMultiplicity.Element) // The foreign key points to the tabel of the related class. { if (relatedClass.Oid.OidColumns.Count != this.foreignKeyColumns.Count) { throw new NDOException(115, "Column count between relation and Oid doesn't match. Type " + relatedClass.FullName + " has an oid column count of " + relatedClass.Oid.OidColumns.Count + ". The Relation " + Parent.FullName + "." + this.fieldName + " has a foreign key column count of " + this.foreignKeyColumns.Count + '.'); } int i = 0; new ForeignKeyIterator(this).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastIndex) { OidColumn oidColumn = (OidColumn)relatedClass.Oid.OidColumns[i]; if (!isEnhancing && fkColumn.Size == 0) { fkColumn.Size = oidColumn.Size; } fkColumn.SystemType = oidColumn.SystemType; i++; } ); } else // List relation. The foreign key points to the own table. { if (Parent.Oid.OidColumns.Count != this.foreignKeyColumns.Count) { throw new NDOException(115, "Column count between relation and Oid doesn't match. Type " + Parent.FullName + " has an oid column count of " + Parent.Oid.OidColumns.Count + ". The Relation " + Parent.FullName + "." + this.fieldName + " has a foreign key column count of " + this.foreignKeyColumns.Count + '.'); } int i = 0; new ForeignKeyIterator(this).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastIndex) { OidColumn oidColumn = (OidColumn)Parent.Oid.OidColumns[i]; if (!isEnhancing && fkColumn.Size == 0) { fkColumn.Size = oidColumn.Size; } fkColumn.SystemType = oidColumn.SystemType; i++; } ); } }