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(""); }
/// <summary> /// KL: /// Similar to WriteColumn. Will send the appropriate dataType and propertyName to /// _cb.AppendAutomaticProperty to be written. /// /// This method was needed to support composite foreign keys. /// </summary> /// <param name="foreignKey"></param> private void WriteForeignKey(DatabaseConstraint foreignKey) { // get the reference table var refTable = foreignKey.ReferencedTable(_table.DatabaseSchema); //we inherit from it instead (problem with self-joins) if (Equals(refTable, _inheritanceTable)) { return; } if (refTable == null) { //we can't find the foreign key table, so just write the columns WriteForeignKeyColumns(foreignKey, ""); return; } var propertyName = _codeWriterSettings.Namer.ForeignKeyName(_table, foreignKey); var dataType = refTable.NetName; _cb.AppendAutomaticProperty(dataType, propertyName); if (IsEntityFramework() && _codeWriterSettings.UseForeignKeyIdProperties) { WriteForeignKeyColumns(foreignKey, propertyName); } }
private string ForeignKeyTableName(DatabaseConstraint foreignKey) { var foreignKeyTable = foreignKey.ReferencedTable(_table.DatabaseSchema); return((foreignKeyTable != null) ? TableName(foreignKeyTable) : EscapeName(foreignKey.RefersToTable)); }
/// <summary> /// Returns the name of a foreign key property for a given foreign key. /// </summary> /// <param name="table">The table.</param> /// <param name="foreignKey">The foreign key.</param> /// <returns></returns> /// <remarks> /// If it is a simple foreign key, it is the NetName of the column /// if it is a composite foreign key, it is the NetName of the foreign table /// if there is a collision with the class name, append "Key" /// If there are multiple foreign keys to one table, ensure they are unique. /// </remarks> public virtual string ForeignKeyName(DatabaseTable table, DatabaseConstraint foreignKey) { var refTable = foreignKey.ReferencedTable(table.DatabaseSchema); if (refTable == null) { //we can't find the foreign key table, so just write the columns return(null); } //This is a name for the foreign key. Only used for composite keys. var propertyName = refTable.NetName; //if there is only one column (not composite) use the netName of that column if (foreignKey.Columns.Count == 1) { var columnName = foreignKey.Columns.Single(); var column = table.FindColumn(columnName); //if it is a primary key, we've used the original name for a scalar property if (!column.IsPrimaryKey) { propertyName = column.NetName; } } else //composite keys { // Check whether the referenced table is used in any other key. This ensures that the property names // are unique. if (table.ForeignKeys.Count(x => x.RefersToTable == foreignKey.RefersToTable) > 1) { // Append the key name to the property name. In the event of multiple foreign keys to the same table // This will give the consumer context. propertyName += foreignKey.Name; } } // Ensures that property name cannot be the same as class name if (propertyName == table.NetName) { propertyName += "Key"; } return(propertyName); }
/// <summary> /// Returns the name of a foreign key property for a given foreign key. /// </summary> /// <param name="table">The table.</param> /// <param name="foreignKey">The foreign key.</param> /// <returns></returns> /// <remarks> /// If it is a simple foreign key, it is the NetName of the column /// if it is a composite foreign key, it is the NetName of the foreign table /// if there is a collision with the class name, append "Key" /// If there are multiple foreign keys to one table, ensure they are unique. /// </remarks> public virtual string ForeignKeyName(DatabaseTable table, DatabaseConstraint foreignKey) { var refTable = foreignKey.ReferencedTable(table.DatabaseSchema); var propertyName = refTable.Name; if (foreignKey.Columns.Count == 1) { var columnName = foreignKey.Columns[0]; if (columnName.Equals("CreatedUserID") || columnName.Equals("LastUpdatedUserID")) { return($"{columnName.Remove(columnName.LastIndexOf("UserID"))}{propertyName}"); } if (columnName.Equals("Driver1ID") || columnName.Equals("Driver2ID")) { return($"{columnName.Remove(columnName.LastIndexOf("ID"))}{propertyName}"); } } var foreignKeysToRefTableCount = table.ForeignKeys.Count(x => x.RefersToTable == foreignKey.RefersToTable); if (foreignKeysToRefTableCount > 1) { // Append the key name to the property name. In the event of multiple foreign keys to the same table // This will give the consumer context. propertyName += foreignKey.Name; } if (propertyName == table.Name) { var columnName = foreignKey.Columns.Single(); var column = table.FindColumn(columnName); if (!column.IsPrimaryKey) { propertyName = column.NetName; } } return(propertyName); }
private void WriteForeignKey(DatabaseConstraint foreignKey) { // get the reference table var refTable = foreignKey.ReferencedTable(table.DatabaseSchema); if (refTable == null) { //we can't find the foreign key table, so just write the columns WriteForeignKeyProperties(foreignKey, ""); return; } var propertyName = codeWriterSettings.Namer.ForeignKeyName(table, foreignKey); var dataType = refTable.NetName; classBuilder.AppendAutomaticProperty(dataType, propertyName); if (false && codeWriterSettings.UseForeignKeyIdProperties) { WriteForeignKeyProperties(foreignKey, propertyName); } }
public void TestReferencedTableViaConstraintName() { //create a schema var schema = new DatabaseSchema(null, SqlType.SqlServer); schema.AddTable("Products") .AddColumn("ProductId").AddPrimaryKey() .AddColumn("ProductName") .AddColumn("CategoryId") .AddTable("Categories") .AddColumn("CategoryId").AddPrimaryKey("CategoryPK") .AddColumn("CategoryName") ; //look at the schema var categories = schema.FindTableByName("Categories"); var products = schema.FindTableByName("Products"); //from the database we normally get a RefersToTable defined. //sometimes we don't- we just get the name of the pk constraint //so here we simulate that var fk = new DatabaseConstraint { ConstraintType = ConstraintType.ForeignKey, TableName = "Categories", RefersToConstraint = "CategoryPK" }; fk.Columns.Add("CategoryId"); products.AddConstraint(fk); //act var referencedTable = fk.ReferencedTable(schema); //assert Assert.AreEqual(categories, referencedTable); }