/// <summary> /// </summary> /// <param name="source"></param> /// <param name="foreignColumn"></param> /// <param name="foreignTableName"></param> /// <returns></returns> public static TableAssociation FromChildManyToMany(TableEntity source, IMemberColumnSchema foreignColumn, string foreignTableName) { TableAssociation association = null; //ASpNetUser -> AspNetUserInRole -> AspnetRole IEntity intermediaryEntity = EntityStore.Instance.GetEntity(foreignColumn.Table.FullName) ?? EntityStore.Instance.GetExcludedEntity(foreignColumn.Table.FullName); IEntity rightEntity = EntityStore.Instance.GetEntity(foreignTableName); if (intermediaryEntity != null && rightEntity != null) { int leftIndex = source.EntityKeyName.Equals(foreignColumn.Table.ForeignKeys[0].PrimaryKeyMemberColumns[0].Table.Name, StringComparison.OrdinalIgnoreCase) ? 0 : 1; int rightIndex = leftIndex == 1 ? 0 : 1; var intermediaryAssocation = new TableAssociation(foreignColumn.Table.ForeignKeys[rightIndex], AssociationType.ManyToMany, rightEntity, intermediaryEntity, false, isChildManyToMany: true, sourceManyToManyTable: source); association = new TableAssociation(foreignColumn.Table.ForeignKeys[leftIndex], AssociationType.ManyToMany, source, intermediaryEntity, true, intermediaryAssociation: intermediaryAssocation, isChildManyToMany: true); //End Association between AspNetUser -> ASpNetRole with Intermediary table as a property } if (association == null || association.Properties.Count <= 0 || String.IsNullOrEmpty(association.AssociationKey)) { return(null); } return(association); }
/// <summary> /// </summary> /// <param name="source"></param> /// <param name="tableKeySchema"></param> /// <returns></returns> public static TableAssociation FromChildPrimaryKey(TableEntity source, ITableKeySchema tableKeySchema) { //In Child Associations, the ForeignKey should be the associated entity IEntity associationEntity = EntityStore.Instance.GetEntity(tableKeySchema.ForeignKeyTable.FullName); if (associationEntity == null && !Configuration.Instance.IncludeManyToManyEntity && tableKeySchema.ForeignKeyTable.IsManyToMany()) { associationEntity = EntityStore.Instance.GetExcludedEntity(tableKeySchema.ForeignKeyTable.FullName); } if (associationEntity == null) { return(null); } TableAssociation association = null; foreach (IMemberColumnSchema foreignColumn in tableKeySchema.ForeignKeyMemberColumns) { //Added a check to see if the FK is also a Foreign composite key (http://community.codesmithtools.com/forums/t/10266.aspx). bool isForeignKeyAlsoComposite = foreignColumn.Table.HasPrimaryKey && foreignColumn.Table.PrimaryKey.MemberColumns.Count > 1 && foreignColumn.IsPrimaryKeyMember && foreignColumn.IsForeignKeyMember; if (!foreignColumn.IsPrimaryKeyMember || isForeignKeyAlsoComposite) { if (foreignColumn.Table.IsManyToMany()) { //&& foreignTable != null) // NOTE: This can because a ManyToMany can be to itself. ITableSchema foreignTable = GetToManyTable(foreignColumn.Table, source.EntitySource) ?? source.EntitySource; association = FromChildManyToMany(source, foreignColumn, foreignTable.FullName); } else { var type = AssociationType.OneToMany; if (tableKeySchema.ForeignKeyMemberColumns.Count(m => m.AllowDBNull) == tableKeySchema.ForeignKeyMemberColumns.Count) { type = AssociationType.ZeroOrOneToMany; } else if (!isForeignKeyAlsoComposite && tableKeySchema.ForeignKeyMemberColumns.Count(m => m.IsUnique || m.IsPrimaryKeyMember) == tableKeySchema.ForeignKeyMemberColumns.Count) { type = AssociationType.OneToZeroOrOne; } association = new TableAssociation(tableKeySchema, type, source, associationEntity, true); } } else if (GetToManyTable(foreignColumn.Table, source.EntitySource) == null) { association = new TableAssociation(tableKeySchema, AssociationType.OneToZeroOrOne, source, associationEntity, true); } } //End Association between AspNetUser -> ASpNetRole with Intermediary table as a property if (association == null || association.Properties.Count <= 0 || String.IsNullOrEmpty(association.AssociationKey)) { return(null); } return(association); }
/// <summary> /// Populates the Child Associations /// </summary> private void GetChildAssociations() { foreach (TableKeySchema tableKeySchema in EntitySource.PrimaryKeys) { IAssociation association = TableAssociation.FromChildPrimaryKey(this, tableKeySchema); // Always overwrite the previous associations if they exist because this is the parent association. if (association != null && !String.IsNullOrEmpty(association.AssociationKey)) { AssociationMap[association.AssociationKey] = association; } } }
/// <summary> /// Populates the Parent Associations /// </summary> private void GetParentAssociations() { if (EntitySource.IsManyToMany()) { TableAssociation association = TableAssociation.FromParentManyToMany(this); if (association != null && !AssociationMap.ContainsKey(association.AssociationKey)) { AssociationMap.Add(association.AssociationKey, association); return; } } foreach (TableKeySchema tableKeySchema in EntitySource.ForeignKeys) { TableAssociation association = TableAssociation.FromParentForeignKey(this, tableKeySchema); if (association != null && !AssociationMap.ContainsKey(association.AssociationKey)) { AssociationMap.Add(association.AssociationKey, association); } } }
/// <summary> /// Gets a parent many to many association from a foreign key. /// </summary> /// <param name="source"></param> /// <returns></returns> public static TableAssociation FromParentManyToMany(TableEntity source) { if (!source.EntitySource.IsManyToMany()) { return(null); } //ASpNetUser -> AspNetUserInRole -> AspnetRole ITableSchema rightTable = GetToManyTable(source.EntitySource, source.EntitySource); ITableSchema leftTable = GetToManyTable(source.EntitySource, rightTable) ?? GetToManyTable(source.EntitySource, source.EntitySource); // This could be a Many-To-Many relation ship to the same table User (User) -> UserMappings <- User (Usee). if (leftTable == null || rightTable == null) { return(null); } IEntity rightEntity = EntityStore.Instance.GetEntity(rightTable.FullName); IEntity leftEntity = EntityStore.Instance.GetEntity(leftTable.FullName); if (leftEntity == null || rightEntity == null) { return(null); } int leftIndex = leftEntity.EntityKeyName.Equals(source.EntitySource.ForeignKeys[0].PrimaryKeyMemberColumns[0].Table.Name, StringComparison.OrdinalIgnoreCase) ? 0 : 1; int rightIndex = leftIndex == 1 ? 0 : 1; var intermediaryAssocation = new TableAssociation(source.EntitySource.ForeignKeys[rightIndex], AssociationType.ManyToMany, source, rightEntity, true); var association = new TableAssociation(source.EntitySource.ForeignKeys[leftIndex], AssociationType.ManyToMany, source, leftEntity, true, intermediaryAssociation: intermediaryAssocation); //End Association between AspNetUser -> ASpNetRole with Intermediary table as a property if (association.Properties.Count <= 0 || String.IsNullOrEmpty(association.AssociationKey)) { return(null); } return(association); }
/// <summary> /// Gets a parent association from a foreign key. /// </summary> /// <param name="source"></param> /// <param name="tableKeySchema"></param> /// <returns></returns> public static TableAssociation FromParentForeignKey(TableEntity source, ITableKeySchema tableKeySchema) { //In Parent Associations, the Primary table should be the Associated IEntity IEntity foreignEntity = EntityStore.Instance.GetEntity(tableKeySchema.PrimaryKeyTable.FullName); if (foreignEntity == null) { Trace.WriteLine("Foreign Key not generated since related Table not included in generation"); return(null); } bool isParentMany = false; bool isParentOne = false; bool isParentOneOrZero = false; bool isParentUnique = tableKeySchema.PrimaryKeyMemberColumns.Count(m => m.IsUnique || m.IsPrimaryKeyMember) == tableKeySchema.PrimaryKeyMemberColumns.Count; if (isParentUnique && tableKeySchema.PrimaryKeyMemberColumns.Count(m => m.AllowDBNull) != tableKeySchema.PrimaryKeyMemberColumns.Count) { isParentOne = true; } else if (isParentUnique && tableKeySchema.PrimaryKeyMemberColumns.Count(m => m.AllowDBNull) == tableKeySchema.PrimaryKeyMemberColumns.Count) { isParentOneOrZero = true; } else { isParentMany = true; } bool isForeignKeyAlsoComposite = tableKeySchema.ForeignKeyTable.HasPrimaryKey && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Count > 1; bool isChildMany = false; bool isChildOne = false; bool isChildOneOrZero = false; bool isChildUnique = !isForeignKeyAlsoComposite && tableKeySchema.ForeignKeyMemberColumns.Count(m => m.IsUnique || m.IsPrimaryKeyMember) == tableKeySchema.ForeignKeyMemberColumns.Count; if (isChildUnique && tableKeySchema.ForeignKeyMemberColumns.Count(m => m.AllowDBNull) != tableKeySchema.ForeignKeyMemberColumns.Count) { isChildOne = true; } else if (isChildUnique && tableKeySchema.ForeignKeyMemberColumns.Count(m => m.AllowDBNull) == tableKeySchema.ForeignKeyMemberColumns.Count) { isChildOneOrZero = true; } else { isChildMany = true; } var type = AssociationType.ManyToOne; if (isChildMany && isParentMany) { type = AssociationType.ManyToMany; } else if (isChildMany && isParentOne) { type = AssociationType.ManyToOne; } else if (isChildMany && isParentOneOrZero) { type = AssociationType.ManyToZeroOrOne; } else if (isChildOne && isParentMany) { type = AssociationType.OneToMany; } else if (isChildOne && isParentOne) { type = AssociationType.OneToOne; } else if (isChildOne && isParentOneOrZero) { type = AssociationType.OneToZeroOrOne; } else if (isChildOneOrZero && isParentMany) { type = AssociationType.ZeroOrOneToMany; } else { Debug.WriteLine("Contact support cause you have a crazy up schema."); } var association = new TableAssociation(tableKeySchema, type, source, foreignEntity, false); if (association.Properties.Count <= 0 || String.IsNullOrEmpty(association.AssociationKey)) { return(null); } return(association); }