public static string CreateOneToManyAssociation(this TableData table, TableData foreignTable, string columnNames, string foreignColumnNames, string constraintName) { // create an IEnumerable<> with the type of the (main) table's type builder var typedEnumerableType = typeof(IEnumerable <>).MakeGenericType(table.TypeBuilder); // use the table's name as property name var propertyName = $"{table.ExplorerItem.Text}"; var i = 1; while (!foreignTable.PropertyAndFieldNames.Add(propertyName)) { propertyName = $"{table.ExplorerItem.Text}{i++}"; } // create a property in the foreign key's target table var property = foreignTable.TypeBuilder.DefineProperty(propertyName, typedEnumerableType); // create a getter for the property var propertyGetter = foreignTable.TypeBuilder.DefineGetter(property); // obtain ResolveOneToMany method var resolveOneToManyMethod = typeof(Entity).GetMethod("ResolveOneToMany", BindingFlags.Instance | BindingFlags.NonPublic).MakeGenericMethod(table.TypeBuilder); // "implement" the method to obtain and return the value by calling 'ResolveOneToMany' var ilGenerator = propertyGetter.GetILGenerator(); // call the method and return the value ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldstr, property.Name); ilGenerator.Emit(OpCodes.Call, resolveOneToManyMethod); ilGenerator.Emit(OpCodes.Ret); property.SetGetMethod(propertyGetter); // add the 'AssociationAttribute' to the property property.AddAssociationAttribute(foreignColumnNames, columnNames, table.Name); // create the explorer item var explorerItem = new ExplorerItem(propertyName, ExplorerItemKind.CollectionLink, ExplorerIcon.OneToMany) { HyperlinkTarget = table.ExplorerItem, ToolTipText = $"{table.ExplorerItem.Text} ({constraintName})" }; foreignTable.ExplorerItem.Children.Add(explorerItem); // create 'backward' association table.CreateManyToOneAssociation(foreignTable, foreignColumnNames, columnNames, constraintName, true); return(propertyName); }