public void WriteWith(DatabaseConstraint foreignKey) { // TODO: refactor this method to be consistent with approach taken for other overload var refTable = foreignKey.ReferencedTable(table.DatabaseSchema); var dataType = refTable.NetName; if (foreignKey.Columns.Count != foreignKey.ReferencedColumns(table.DatabaseSchema).Count()) { throw new InvalidOperationException("Number of foreign key columns does not match number of columns referenced!"); } classBuilder.BeginNest($"public virtual {CodeWriterUtils.GetWithMethodSignature(table, foreignKey, codeWriterSettings)}"); var methodCallParameters = new List <string>(); var propertyName = codeWriterSettings.Namer.ForeignKeyName(table, foreignKey); foreach (var fkc in foreignKey.Columns) { var tc = table.Columns.Single(_tc => _tc.Name == fkc); var parameter = $"{CodeWriterUtils.GetPropertyNameForDatabaseColumn(tc)}"; if (tc.Nullable && CodeWriterUtils.FindDataType(tc).EndsWith("?")) // KE: need the check for the "?" so that we correctly handle reference types like string { using (classBuilder.BeginNest($"if (!{parameter}.HasValue)")) { classBuilder.AppendLine($"{propertyName} = null;"); classBuilder.AppendLine("return this;"); } classBuilder.AppendLine(""); parameter += ".Value"; } methodCallParameters.Add(parameter); } var s = string.Join(", ", methodCallParameters); var referencedColumnNames = foreignKey.ReferencedColumns(table.DatabaseSchema).ToList(); referencedColumnNames.Sort(); var referencedColumns = referencedColumnNames.Select(c => foreignKey.ReferencedTable(table.DatabaseSchema).FindColumn(c)); var methodParameters = CodeWriterUtils.GetMethodParametersForColumns(referencedColumns, codeWriterSettings); var methodName = CodeWriterUtils.GetMethodName(methodParameters, codeWriterSettings, true, CodeWriterUtils.BaseMethodNameGet); var fieldNameForFkTableRepository = NameFixer.ToCamelCase(CodeWriterUtils.GetRepositoryImplementationName(refTable)); classBuilder.AppendLine($"{propertyName} = _{fieldNameForFkTableRepository}.{methodName}({s});"); classBuilder.AppendLine("return this;"); classBuilder.EndNest(); classBuilder.AppendLine(""); }
private A GetOutFkLink(string sourceTable, DatabaseConstraint fk, IDictionary <string, object> o) { var filters = fk.Columns .Select((t, i) => KeyValuePair.Create(fk.ReferencedColumns(_dbInspector.GetSchema()).ToList()[i], o[t])) .ToList(); if (filters.Count == 1) { var id = filters.Single().Value; var title = _dbInspector.GetTitle(fk.RefersToTable, id.ToString()); return(new A(_linkManager.LinkToItem(fk.RefersToTable, id), title, fk.RefersToTable) { Itemscope = true, }); } return(new A(_linkManager.LinkToQuery(fk.RefersToTable, filters)) { Itemscope = true, }); }
private string WriteForeignKey(DatabaseConstraint foreignKey) { var foreignKeyTableName = ForeignKeyTableName(foreignKey); var fkTablePks = foreignKey.ReferencedColumns(_table.DatabaseSchema); //if we can't find other table, we won't list the fk table primary key columns - it *should* be automatic //in practice, SQLServer/Oracle are ok but MySQL will error var fkColumnList = fkTablePks == null ? string.Empty : " (" + GetColumnList(fkTablePks) + ")"; var deleteUpdateRule = string.Empty; if (!string.IsNullOrEmpty(foreignKey.DeleteRule)) { // { CASCADE | NO ACTION | SET DEFAULT | SET NULL } deleteUpdateRule = " ON DELETE " + foreignKey.DeleteRule; } if (!string.IsNullOrEmpty(foreignKey.UpdateRule)) { // { CASCADE | NO ACTION | SET DEFAULT | SET NULL } deleteUpdateRule += " ON UPDATE " + foreignKey.UpdateRule; } if (_table.Name == foreignKeyTableName && !string.IsNullOrEmpty(deleteUpdateRule) && !IsSelfReferencingCascadeAllowed()) { //SqlServer cannot have cascade rules on self-referencing tables deleteUpdateRule = string.Empty; } //arguably we should fully qualify the refersToTable with its schema return(string.Format(CultureInfo.InvariantCulture, "ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3}{4}{5}", TableName(_table), EscapeName(foreignKey.Name), GetColumnList(foreignKey.Columns), foreignKeyTableName, fkColumnList, deleteUpdateRule) + SqlFormatProvider().LineEnding()); }