/// <summary> /// Alter the MappingTable, if there are changed attributes in the mappingTableAttribute /// </summary> /// <param name="ownTypeIsPoly"></param> /// <param name="otherTypeIsPoly"></param> /// <param name="mappingTableAttribute"></param> public void RemapMappingTable(bool ownTypeIsPoly, bool otherTypeIsPoly, MappingTableAttribute mappingTableAttribute) { if (mappingTableAttribute == null && (foreignRelation == null || foreignRelation.mappingTable == null)) { return; } int pos = referencedTypeName.LastIndexOf('.'); string refShortName = this.referencedTypeName.Substring(pos + 1); refShortName = refShortName.Replace("`", string.Empty); string fullName = Parent.FullName; pos = fullName.LastIndexOf('.'); string myShortName = fullName.Substring(pos + 1); myShortName = myShortName.Replace("`", string.Empty); if (MappingTable == null) { AddMappingTable(refShortName, myShortName, otherTypeIsPoly, mappingTableAttribute); } if (mappingTableAttribute != null && mappingTableAttribute.TableName != null) { MappingTable.TableName = mappingTableAttribute.TableName; } RemapForeignMappingTable(myShortName, refShortName, ownTypeIsPoly, otherTypeIsPoly, mappingTableAttribute); }
public void MappingTableAttributeWorks() { NDOMapping mapping = NDOMapping.Create(null); var cls = mapping.AddStandardClass("TestClass", "TestAssembly", null); var relation = cls.AddStandardRelation("relField", "RefTypeName", false, "", false, false); Assert.AreEqual("IDTestClass", relation.ForeignKeyColumns.First().Name); var attr = new MappingTableAttribute(); relation.RemapMappingTable(false, false, attr); Assert.That(relation.MappingTable != null); Assert.AreEqual("relRefTypeNameTestClass", relation.MappingTable.TableName); Assert.AreEqual("IDTestClass", relation.ForeignKeyColumns.First().Name); Assert.AreEqual("IDRefTypeName", relation.MappingTable.ChildForeignKeyColumns.First().Name); attr.TableName = "newTableName"; relation.RemapMappingTable(false, false, attr); Assert.AreEqual("newTableName", relation.MappingTable.TableName); }
public RelationNode(FieldInfo relationFieldInfo, NDORelationAttribute attr, ClassNode parent) { this.parent = parent; this.fieldType = relationFieldInfo.FieldType; Type parentType = relationFieldInfo.ReflectedType; NDOAssemblyName an = new NDOAssemblyName(parentType.Assembly.FullName); string assShortName = an.Name; this.isElement = !(relationFieldInfo.FieldType == typeof(IList) || relationFieldInfo.FieldType.GetInterface("IList") != null || GenericIListReflector.IsGenericIList(relationFieldInfo.FieldType)); // dataType & declaringType always have // - a class/valutype prefix // - an [AssName] prefix this.dataType = new ReflectedType(relationFieldInfo.FieldType).ILName; if (relationFieldInfo.DeclaringType != relationFieldInfo.ReflectedType) { this.declaringType = new ReflectedType(relationFieldInfo.DeclaringType).ILName; } else { this.declaringType = null; } this.name = relationFieldInfo.Name; Type attrType = attr.GetType(); this.relationName = attr.RelationName; this.relationInfo = attr.Info; Type relType; if (isElement) { relType = relationFieldInfo.FieldType; } else { if (attr.RelationType == null && relationFieldInfo.FieldType.IsGenericType) { relType = relationFieldInfo.FieldType.GetGenericArguments()[0]; } else { relType = attr.RelationType; } if (relType == null) { throw new Exception("Can't determine referenced type in relation " + parent.Name + "." + this.name + ". Provide a type parameter for the [NDORelation] attribute."); } } if (relType.IsGenericType && !relType.IsGenericTypeDefinition) { relType = relType.GetGenericTypeDefinition(); } // Related Type hat kein "class " Prefix, hat [assName] nur bei fremden Assemblies. this.relatedType = new ReflectedType(relType, assShortName).ILNameWithoutPrefix; if (relType.IsGenericType) { this.relatedType = this.relatedType.Substring(0, this.relatedType.IndexOf('<')); } object[] attrs = relationFieldInfo.GetCustomAttributes(typeof(ForeignKeyColumnAttribute), true); if (attrs.Length > 0) { this.foreignKeyColumnAttributes = new ForeignKeyColumnAttribute[attrs.Length]; attrs.CopyTo(this.foreignKeyColumnAttributes, 0); } attrs = relationFieldInfo.GetCustomAttributes(typeof(ChildForeignKeyColumnAttribute), true); if (attrs.Length > 0) { this.childForeignKeyColumnAttributes = new ChildForeignKeyColumnAttribute[attrs.Length]; attrs.CopyTo(this.childForeignKeyColumnAttributes, 0); } attrs = relationFieldInfo.GetCustomAttributes(typeof(MappingTableAttribute), true); if (attrs.Length > 0) { MappingTableAttribute = (MappingTableAttribute)attrs[0]; } }
/// <summary> /// Adds a default relation mapping. /// </summary> /// <param name="fieldName">Name of the field</param> /// <param name="referencedTypeName">Type name of the referenced class</param> /// <param name="isElement">True, if multiplicity is 1</param> /// <param name="relationName">Optional relation name</param> /// <param name="ownTypeIsPoly">True, if the class, containing the field, has a persistent base class</param> /// <param name="otherTypeIsPoly">True, if the related type has a persistent base class</param> /// <param name="mappingTableAttribute">If not null, the mapping information comes from this attribute.</param> /// <returns>A new constructed <code>Relation</code> object</returns> public Relation AddStandardRelation(string fieldName, string referencedTypeName, bool isElement, string relationName, bool ownTypeIsPoly, bool otherTypeIsPoly, MappingTableAttribute mappingTableAttribute) { // if (null != Parent) // Parent.this.Changed = true; Relation r = new Relation(this); r.FieldName = fieldName; r.ReferencedTypeName = referencedTypeName; //r.parent = this; r.RelationName = relationName; r.Multiplicity = isElement ? RelationMultiplicity.Element : RelationMultiplicity.List; int pos = referencedTypeName.LastIndexOf('.'); string refShortName = referencedTypeName.Substring(pos + 1); refShortName = refShortName.Replace("`", string.Empty); pos = this.FullName.LastIndexOf('.'); string myShortName = this.FullName.Substring(pos + 1); myShortName = myShortName.Replace("`", string.Empty); Relation foreignRelation = r.ForeignRelation; ForeignKeyColumn fkColumn = r.NewForeignKeyColumn(); // Element->x AND no MappingTable if (isElement && mappingTableAttribute == null && !(foreignRelation != null && foreignRelation.MappingTable != null)) { r.MappingTable = null; // Foreign Key is in the own table and points to rows of the other table fkColumn.Name = "ID" + refShortName; if (otherTypeIsPoly) { r.ForeignKeyTypeColumnName = "TC" + refShortName; } if (relationName != string.Empty) { fkColumn.Name += "_" + relationName; if (otherTypeIsPoly) { r.ForeignKeyTypeColumnName += "_" + relationName; } } } else // List or (Element with Mapping Table) { // These are the reasons for creating a mapping table: // 1. The MappingTableAttribute demands it // 2. We have a n:n relationship // 3. We have a 1:n relationship and the other type is poly // 4. The relation is bidirectional and the other side demands a mapping table bool needsMappingTable = mappingTableAttribute != null || null != foreignRelation && (foreignRelation.Multiplicity == RelationMultiplicity.List && r.Multiplicity == RelationMultiplicity.List) || otherTypeIsPoly && r.Multiplicity == RelationMultiplicity.List || null != foreignRelation && foreignRelation.MappingTable != null; // Foreign Key points to rows of our own table fkColumn.Name = "ID" + myShortName; if (ownTypeIsPoly && needsMappingTable) { r.ForeignKeyTypeColumnName = "TC" + myShortName; } else if (otherTypeIsPoly && !needsMappingTable) { r.ForeignKeyTypeColumnName = "TC" + refShortName; } if (relationName != string.Empty) { fkColumn.Name += "_" + relationName; if (ownTypeIsPoly) { r.ForeignKeyTypeColumnName += "_" + relationName; } } if (needsMappingTable) { r.AddMappingTable(refShortName, myShortName, otherTypeIsPoly, mappingTableAttribute); r.RemapForeignMappingTable(myShortName, refShortName, ownTypeIsPoly, otherTypeIsPoly, mappingTableAttribute); } else { r.MappingTable = null; } } this.relations.Add(r); return(r); }
internal void AddMappingTable(string typeShortName1, string typeShortName2, bool otherTypeIsPoly, MappingTableAttribute mappingTableAttribute) { this.MappingTable = new MappingTable(this); ForeignKeyColumn fkColumn = this.MappingTable.NewForeignKeyColumn(); fkColumn.Name = "ID" + typeShortName1; if (otherTypeIsPoly) { this.MappingTable.ChildForeignKeyTypeColumnName = "TC" + typeShortName1; } if (this.RelationName != null && this.RelationName != string.Empty) { fkColumn.Name += "_" + this.RelationName; if (otherTypeIsPoly) { this.MappingTable.ChildForeignKeyTypeColumnName += "_" + this.RelationName; } } if (mappingTableAttribute != null && mappingTableAttribute.TableName != null) { this.MappingTable.TableName = mappingTableAttribute.TableName; } else { if (typeShortName1.CompareTo(typeShortName2) < 0) { this.MappingTable.TableName = "rel" + typeShortName1 + typeShortName2; } else { this.MappingTable.TableName = "rel" + typeShortName2 + typeShortName1; } } this.MappingTable.ConnectionId = ((Connection)Parent.Parent.Connections.First()).ID; }
internal void RemapForeignMappingTable(string myShortName, string refShortName, bool ownTypeIsPoly, bool otherTypeIsPoly, MappingTableAttribute mappingTableAttribute) { if (this.foreignRelation == null) { return; } if (foreignRelation.MappingTable == null) { foreignRelation.AddMappingTable(myShortName, refShortName, ownTypeIsPoly, mappingTableAttribute); if (otherTypeIsPoly) { foreignRelation.ForeignKeyTypeColumnName = "TC" + refShortName; } } string frFkcName = "ID" + refShortName; // This is going to be the r.ForeignKeyColumnName of the foreign relation string frFtcName = null; if (ownTypeIsPoly) { frFtcName = "TC" + myShortName; // This is going to be the r.MappingTable.ChildForeignKeyColumnName of the foreign relation } if (relationName != string.Empty) { frFkcName += "_" + relationName; if (ownTypeIsPoly) { frFtcName += "_" + relationName; } } ForeignKeyColumn forFkColumn = foreignRelation.ForeignKeyColumns.FirstOrDefault(); forFkColumn.Name = frFkcName; foreignRelation.MappingTable.ChildForeignKeyTypeColumnName = frFtcName; }