static void Main(string[] args) { string projectFolder = System.IO.Path.Combine(CodegenCS.Utils.IO.GetCurrentDirectory().FullName, @"..\AdventureWorks.Business"); CodegenContext context = new CodegenContext(outputFolder: projectFolder + "\\GeneratedCode"); Generator generator = new Generator( context: context, createConnection: () => new System.Data.SqlClient.SqlConnection(@" Data Source=LENOVOFLEX5\SQLEXPRESS; Initial Catalog=AdventureWorks; Integrated Security=True; Application Name=EntityFramework POCO Generator" ), targetFrameworkVersion: 4.72m ); generator.GenerateMultipleFiles(); // generates in memory // since no errors, first modify csproj, then we save all files // Generate all files and add each into to the csproj MSBuildProjectEditor editor = new MSBuildProjectEditor(projectFilePath: projectFolder + @"\AdventureWorks.Business.csproj"); //string templateFile = Path.Combine(CodegenCS.Utils.IO.GetCurrentDirectory().FullName); foreach (var o in context.OutputFilesAbsolute) { editor.AddItem(itemPath: o.Key, itemType: o.Value.ItemType); } editor.Save(); context.SaveFiles(deleteOtherFiles: true); }
/// <summary> /// Generates POCOS /// </summary> /// <param name="targetFolder">Absolute path of the target folder where files will be written</param> public void Generate(string targetFolder) { Console.WriteLine($"TargetFolder: {targetFolder}"); _generatorContext = new CodegenContext(outputFolder: targetFolder); Console.WriteLine("Reading Schema..."); DatabaseSchema schema = Newtonsoft.Json.JsonConvert.DeserializeObject <DatabaseSchema>(File.ReadAllText(_inputJsonSchema)); foreach (var table in schema.Tables) { string entityClassName = GetClassNameForTable(table); var schemaAndtable = new Tuple <string, string>(table.TableSchema, table.TableName); if (!_usedIdentifiers.ContainsKey(schemaAndtable)) { _usedIdentifiers.Add(schemaAndtable, new List <string>() { entityClassName }); } string tableFilePath = GetFileNameForTable(table); Console.WriteLine($"Generating {tableFilePath}..."); using (var writer = _generatorContext.GetOutputFile(relativePath: tableFilePath).Writer) { writer.WriteLine(@"using System;"); writer.WriteLine(@"using System.Collections.Generic;"); writer.WriteLine(); using (writer.WithCBlock($"namespace {Namespace}")) { using (writer.WithCBlock($"public partial class {entityClassName}")) { var columns = table.Columns.Where(c => ShouldProcessColumn(table, c)); foreach (var column in columns) { string propertyName = GetPropertyNameForDatabaseColumn(table, column, _usedIdentifiers[schemaAndtable]); writer.WriteLine($"public {GetTypeDefinitionForDatabaseColumn(table, column) ?? ""} {propertyName} {{ get; set; }}"); } } } } } // since no errors happened, let's save all files _generatorContext.SaveFiles(); Console.WriteLine("Success!"); }
/// <summary> /// Generates POCOS /// </summary> /// <param name="targetFolder">Absolute path of the target folder where files will be written</param> public void Generate(string targetFolder) { Console.WriteLine($"TargetFolder: {targetFolder}"); _generatorContext = new CodegenContext(); Console.WriteLine("Reading Schema..."); LogicalSchema schema = Newtonsoft.Json.JsonConvert.DeserializeObject <LogicalSchema>(File.ReadAllText(_inputJsonSchema)); //schema.Tables = schema.Tables.Select(t => Map<LogicalTable, Table>(t)).ToList<Table>(); CodegenOutputFile writer = null; if (SingleFile) { writer = _generatorContext[singleFileName]; writer .WriteLine(@"using System;") .WriteLine(@"using System.Collections.Generic;") .WriteLine(@"using System.ComponentModel.DataAnnotations;") .WriteLine(@"using System.ComponentModel.DataAnnotations.Schema;") .WriteLine(@"using System.Linq;"); if (GenerateActiveRecord) { writer.WriteLine(@"using Dapper;"); } writer .WriteLine() .WriteLine($"namespace {Namespace}").WriteLine("{").IncreaseIndent(); } if (GenerateActiveRecord) { using (var writerConnectionFactory = _generatorContext["..\\IDbConnectionFactory.cs"]) { writerConnectionFactory.WriteLine($@" using System; using System.Data; using System.Data.SqlClient; namespace {Namespace} {{ public class IDbConnectionFactory {{ public static IDbConnection CreateConnection() {{ string connectionString = @""Data Source=MYWORKSTATION\\SQLEXPRESS; Initial Catalog=AdventureWorks; Integrated Security=True;""; return new SqlConnection(connectionString); }} }} }} "); } } foreach (var table in schema.Tables.OrderBy(t => GetClassNameForTable(t))) { if (table.TableType == "VIEW") { continue; } GeneratePOCO(table); } if (SingleFile) { writer.DecreaseIndent().WriteLine("}"); // end of namespace } // since no errors happened, let's save all files _generatorContext.SaveFiles(outputFolder: targetFolder); Console.WriteLine("Success!"); }
/// <summary> /// Generates POCOS /// </summary> public void Generate() { while (string.IsNullOrEmpty(InputJsonSchema)) { Console.WriteLine($"[Choose an Input JSON Schema File]"); Console.Write($"Input file: "); InputJsonSchema = Console.ReadLine(); } while (string.IsNullOrEmpty(TargetFolder)) { Console.WriteLine($"[Choose a Target Folder]"); Console.Write($"Target Folder: "); TargetFolder = Console.ReadLine(); } while (string.IsNullOrEmpty(Namespace)) { Console.WriteLine($"[Choose a Namespace]"); Console.Write($"Namespace: "); Namespace = Console.ReadLine(); } _generatorContext = new CodegenContext(); Console.WriteLine("Reading Schema..."); LogicalSchema schema = Newtonsoft.Json.JsonConvert.DeserializeObject <LogicalSchema>(File.ReadAllText(InputJsonSchema)); //schema.Tables = schema.Tables.Select(t => Map<LogicalTable, Table>(t)).ToList<Table>(); CodegenOutputFile writer = null; if (SingleFile) { writer = _generatorContext[singleFileName]; writer .WriteLine(@"using System;") .WriteLine(@"using System.Collections.Generic;") .WriteLine(@"using System.ComponentModel.DataAnnotations;") .WriteLine(@"using System.ComponentModel.DataAnnotations.Schema;") .WriteLine(@"using System.Linq;"); if (GenerateActiveRecord) { writer.WriteLine(@"using Dapper;"); } if (TrackPropertiesChange) { writer.WriteLine(@"using System.ComponentModel;"); } writer .WriteLine() .WriteLine($"namespace {Namespace}").WriteLine("{").IncreaseIndent(); } if (GenerateCrudExtensions) { _dbConnectionCrudExtensions = _generatorContext[CrudExtensionsFile]; _dbConnectionCrudExtensions.Write(@" using Dapper; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Runtime.CompilerServices; "); _dbConnectionCrudExtensions .WriteLine() .WriteLine($"namespace {Namespace}").WriteLine("{").IncreaseIndent() .WriteLine($"public static class {CrudExtensionsClass}").WriteLine("{").IncreaseIndent(); } if (GenerateActiveRecord) { using (var writerConnectionFactory = _generatorContext[ActiveRecordIDbConnectionFactoryFile]) { writerConnectionFactory.WriteLine($@" using System; using System.Data; using System.Data.SqlClient; namespace {Namespace} {{ public class IDbConnectionFactory {{ public static IDbConnection CreateConnection() {{ string connectionString = @""Data Source=MYWORKSTATION\\SQLEXPRESS; Initial Catalog=AdventureWorks; Integrated Security=True;""; return new SqlConnection(connectionString); }} }} }} "); } } foreach (var table in schema.Tables.OrderBy(t => GetClassNameForTable(t))) { if (!ShouldProcessTable(table)) { continue; } GeneratePOCO(table); } if (GenerateCrudExtensions) { _dbConnectionCrudExtensions .DecreaseIndent().WriteLine("}") // end of class .DecreaseIndent().WriteLine("}"); // end of namespace } if (SingleFile) { writer.DecreaseIndent().WriteLine("}"); // end of namespace } // since no errors happened, let's save all files _generatorContext.SaveFiles(outputFolder: TargetFolder); Console.WriteLine("Success!"); }
/// <summary> /// Generates Entities and DbContext /// </summary> public void Generate() { while (string.IsNullOrEmpty(InputJsonSchema)) { Console.WriteLine($"[Choose an Input JSON Schema File]"); Console.Write($"Input file: "); InputJsonSchema = Console.ReadLine(); } while (string.IsNullOrEmpty(TargetFolder)) { Console.WriteLine($"[Choose a Target Folder]"); Console.Write($"Target Folder: "); TargetFolder = Console.ReadLine(); } while (string.IsNullOrEmpty(Namespace)) { Console.WriteLine($"[Choose a Namespace]"); Console.Write($"Namespace: "); Namespace = Console.ReadLine(); } while (string.IsNullOrEmpty(ContextName)) { Console.WriteLine($"[Choose a DbContext Name]"); Console.Write($"DbContext Name: "); ContextName = Console.ReadLine(); } _generatorContext = new CodegenContext(); Console.WriteLine("Reading Schema..."); LogicalSchema schema = Newtonsoft.Json.JsonConvert.DeserializeObject <LogicalSchema>(File.ReadAllText(InputJsonSchema)); //schema.Tables = schema.Tables.Select(t => Map<LogicalTable, Table>(t)).ToList<Table>(); // Define a unique property name for each column foreach (var table in schema.Tables) { if (!ShouldProcessTable(table)) { continue; } var columns = table.Columns.Where(c => ShouldProcessColumn(table, c)); foreach (var column in columns) { string propertyName = GetPropertyNameForDatabaseColumn(table, column); } } // Define a unique property name for each navigation property and reverse navigation property foreach (var table in schema.Tables) { foreach (var fk in table.ForeignKeys.ToList()) { var fkTable = table; var pkTable = schema.Tables.SingleOrDefault(t => t.TableSchema == fk.PKTableSchema && t.TableName == fk.PKTableName); if (pkTable == null) { Console.WriteLine($"Can't find table {fk.PKTableName}"); continue; } var reverseFk = pkTable.ChildForeignKeys.Single(rfk => rfk.ForeignKeyConstraintName == fk.ForeignKeyConstraintName); SetForeignKeyPropertyNames(pkTable, fkTable, fk, reverseFk); } } #region foreach (var table in schema.Tables) foreach (var table in schema.Tables) { if (!ShouldProcessTable(table)) { continue; } string entityClassName = GetClassNameForTable(table); string tableFilePath = GetFileNameForTable(table); Console.WriteLine($"Generating {tableFilePath}..."); using (var writer = _generatorContext[tableFilePath]) { writer.WriteLine(@"using System;"); writer.WriteLine(@"using System.Collections.Generic;"); if (withAttributes) { writer.WriteLine(@"using System.ComponentModel.DataAnnotations;"); writer.WriteLine(@"using System.ComponentModel.DataAnnotations.Schema;"); } writer.WriteLine(); using (writer.WithCBlock($"namespace {Namespace}")) { if (withAttributes && table.TableSchema != "dbo") //TODO or table different than class name? { writer.WriteLine($"[Table(\"{table.TableName}\", Schema = \"{table.TableSchema}\")]"); } else if (entityClassName.ToLower() != table.TableName.ToLower()) { writer.WriteLine($"[Table(\"{table.TableName}\")]"); } using (writer.WithCBlock($"public partial class {entityClassName}")) { if (table.ChildForeignKeys.Any()) { using (writer.WithCBlock($"public {entityClassName}()")) { foreach (var fk in table.ChildForeignKeys.OrderBy(fk => fk.NavigationPropertyName)) { var fkTable = schema.Tables.Single(t => t.TableSchema == fk.FKTableSchema && t.TableName == fk.FKTableName); writer.WriteLine($"{fk.NavigationPropertyName} = new HashSet<{GetClassNameForTable(fkTable)}>();"); } } writer.WriteLine(); } var columns = table.Columns.Where(c => ShouldProcessColumn(table, c)); foreach (var column in columns) { string propertyName = GetPropertyNameForDatabaseColumn(table, column); string clrType = GetTypeDefinitionForDatabaseColumn(table, column) ?? ""; if (withAttributes) { if (column.IsPrimaryKeyMember) { writer.WriteLine("[Key]"); } if (!column.IsNullable && clrType == "System.String" && !column.IsPrimaryKeyMember) // reference types are always nullable (no need "?"), so must specify this. { writer.WriteLine($"[Required]"); } string typeName = null; // TODO: combine with identical block if (column.SqlDataType == "datetime" || column.SqlDataType == "smallmoney" || column.SqlDataType == "money" || column.SqlDataType == "xml") { typeName = column.SqlDataType; } else if (column.SqlDataType == "decimal") { typeName = $"decimal({column.NumericPrecision}, {column.NumericScale})"; } if (column.ColumnName != propertyName && typeName != null) { writer.WriteLine($"[Column(\"{column.ColumnName}\", TypeName = \"{typeName}\")]"); } else if (column.ColumnName != propertyName && typeName == null) { writer.WriteLine($"[Column(\"{column.ColumnName}\")]"); } else if (column.ColumnName == propertyName && typeName != null) { writer.WriteLine($"[Column(TypeName = \"{typeName}\")]"); } if (clrType == "System.String" && column.MaxLength != -1) { writer.WriteLine($"[StringLength({column.MaxLength})]"); } } writer.WriteLine($"public {clrType} {propertyName} {{ get; set; }}"); } if (table.ForeignKeys.Any() || table.ChildForeignKeys.Any()) { writer.WriteLine(); } foreach (var childToParentFK in table.ForeignKeys.OrderBy(fk => fk.NavigationPropertyName)) { var fkTable = table; var pkTable = schema.Tables.Single(t => t.TableSchema == childToParentFK.PKTableSchema && t.TableName == childToParentFK.PKTableName); var parentToChildFK = pkTable.ChildForeignKeys.Single(fk => fk.ForeignKeyConstraintName == childToParentFK.ForeignKeyConstraintName); var fkCol = childToParentFK.Columns.First().FKColumnName; //TODO: composite keys Console.WriteLine($"{table.TableName}{fkCol}"); if (withAttributes) { writer.WriteLine($"[ForeignKey(nameof({table.ColumnPropertyNames[fkCol]}))]"); writer.WriteLine($"[InverseProperty(nameof({GetClassNameForTable(pkTable)}.{parentToChildFK.NavigationPropertyName}))]"); } writer.WriteLine($"public virtual {GetClassNameForTable(pkTable)} {childToParentFK.NavigationPropertyName} {{ get; set; }}"); } foreach (var parentToChildFK in table.ChildForeignKeys.OrderBy(fk => fk.NavigationPropertyName)) { var pkTable = table; var fkTable = schema.Tables.Single(t => t.TableSchema == parentToChildFK.FKTableSchema && t.TableName == parentToChildFK.FKTableName); var childToParentFK = fkTable.ForeignKeys.Single(fk => fk.ForeignKeyConstraintName == parentToChildFK.ForeignKeyConstraintName); var fkCol = parentToChildFK.Columns.First().FKColumnName; //TODO: composite keys if (withAttributes) { //writer.WriteLine($"[InverseProperty(nameof({GetClassNameForTable(fkTable)}.{fk.ReverseNavigationPropertyName}))]"); // some cases attribute is set by nameof? writer.WriteLine($"[InverseProperty(\"{childToParentFK.NavigationPropertyName}\")]"); // some cases attribute is set by nameof? } writer.WriteLine($"public virtual ICollection<{GetClassNameForTable(fkTable)}> {parentToChildFK.NavigationPropertyName} {{ get; set; }} "); } } } } } #endregion #region DbContext using (var dbContextWriter = _generatorContext[ContextName + ".cs"]) { dbContextWriter.WriteLine("using System;"); dbContextWriter.WriteLine("using Microsoft.EntityFrameworkCore;"); dbContextWriter.WriteLine("using Microsoft.EntityFrameworkCore.Metadata;"); dbContextWriter.WriteLine(""); using (dbContextWriter.WithCBlock($"namespace {Namespace}")) { using (dbContextWriter.WithCBlock($"public partial class {ContextName} : DbContext")) { using (dbContextWriter.WithCBlock($"public {ContextName}()")) { } dbContextWriter.WriteLine(); using (dbContextWriter.WithCBlock($"public {ContextName}(DbContextOptions<{ContextName}> options){Environment.NewLine} : base(options)")) { } dbContextWriter.WriteLine(); foreach (var table in schema.Tables.OrderBy(t => GetClassNameForTable(t))) { if (!ShouldProcessTable(table)) { continue; } string entityClassName = GetClassNameForTable(table); dbContextWriter.WriteLine($"public virtual DbSet<{entityClassName}> {entityClassName} {{ get; set; }}"); } dbContextWriter.WriteLine(); dbContextWriter.WriteLine(); dbContextWriter.WriteLine(); using (dbContextWriter.WithCBlock($"protected override void OnModelCreating(ModelBuilder modelBuilder)")) { foreach (var table in schema.Tables.OrderBy(t => GetClassNameForTable(t))) { if (!ShouldProcessTable(table)) { continue; } string entityClassName = GetClassNameForTable(table); using (dbContextWriter.WithIndent($"modelBuilder.Entity<{GetClassNameForTable(table)}>(entity =>{Environment.NewLine}{{{Environment.NewLine}", $"{Environment.NewLine}}});{Environment.NewLine}{Environment.NewLine}")) { var pkCols = table.Columns.Where(c => c.IsPrimaryKeyMember); if (pkCols.Any() && !string.IsNullOrEmpty(table.PrimaryKeyName)) { if (pkCols.Count() == 1) { dbContextWriter.Write($"entity.HasKey(e => e.{GetPropertyNameForDatabaseColumn(table, pkCols.Single())})"); } else { dbContextWriter.Write($"entity.HasKey(e => new {{ " + string.Join(", ", pkCols.Select(pk => $"e.{GetPropertyNameForDatabaseColumn(table, pk)}")) + $"}})"); } List <string> commands = new List <string>(); dbContextWriter.Write($"{Environment.NewLine} .HasName(\"{table.PrimaryKeyName}\")"); //commands.Add($" .HasName(\"{table.PrimaryKeyName}\");"); if (!table.PrimaryKeyIsClustered) { dbContextWriter.Write($"{Environment.NewLine} .IsClustered(false)"); } //commands.Add($" .IsClustered(false);"); //Extensions.WriteChainedMethods(dbContextWriter, commands); // dbContextWriter.WriteChainedMethods(commands); - CSX doesn't allow extensions dbContextWriter.WriteLine($";{Environment.NewLine}"); } else { dbContextWriter.WriteLine($"entity.HasNoKey();{Environment.NewLine}"); } if (!withAttributes) { dbContextWriter.WriteLine($"entity.ToTable(\"{table.TableName}\", \"{table.TableSchema}\");{Environment.NewLine}"); } if (!string.IsNullOrEmpty(table.TableDescription)) { dbContextWriter.WriteLine($"entity.HasComment(\"{table.TableDescription.Replace("\"", "\\\"")}\");"); dbContextWriter.WriteLine(); } dbContextWriter.Write($"{null}"); foreach (var index in table.Indexes .Where(i => i.PhysicalType == "CLUSTERED" || i.PhysicalType == "NONCLUSTERED") .Where(i => i.LogicalType != "PRIMARY_KEY") .Where(i => i.Columns.Any()) .OrderBy(i => GetPropertyNameForDatabaseColumn(table, i.Columns.First().ColumnName)) ) { dbContextWriter.Write($"entity.HasIndex(e => e.{GetPropertyNameForDatabaseColumn(table, index.Columns.First().ColumnName)})"); dbContextWriter.Write($"{Environment.NewLine} .HasName(\"{index.IndexName}\")"); if (index.LogicalType == "UNIQUE_INDEX" || index.LogicalType == "UNIQUE_CONSTRAINT") { dbContextWriter.Write($"{Environment.NewLine} .IsUnique()"); } dbContextWriter.WriteLine($";{Environment.NewLine}"); } foreach (var column in table.Columns .OrderBy(c => c.IsPrimaryKeyMember ? 0 : 1) .ThenBy(c => c.IsPrimaryKeyMember ? c.OrdinalPosition : 0) // respect PK order... .ThenBy(c => GetPropertyNameForDatabaseColumn(table, c)) // but for other columns do alphabetically ) { dbContextWriter.Write($"entity.Property(e => e.{GetPropertyNameForDatabaseColumn(table, column)})"); if (!withAttributes && column.ColumnName != GetPropertyNameForDatabaseColumn(table, column)) { dbContextWriter.Write($"{Environment.NewLine} .HasColumnName(\"{column.ColumnName}\")"); } string typeName = null; // TODO: combine with identical block if (column.SqlDataType == "datetime" || column.SqlDataType == "smallmoney" || column.SqlDataType == "money" || column.SqlDataType == "xml") { typeName = column.SqlDataType; } else if (column.SqlDataType == "decimal") { typeName = $"decimal({column.NumericPrecision}, {column.NumericScale})"; } if (typeName != null) { dbContextWriter.Write($"{Environment.NewLine} .HasColumnType(\"{typeName}\")"); } string defaultSetting = column.DefaultSetting; if (!string.IsNullOrEmpty(defaultSetting)) { try { Type clrType = Type.GetType(column.ClrType); if ((clrType == typeof(int) || clrType == typeof(decimal) || clrType == typeof(byte) || clrType == typeof(float) || clrType == typeof(long) || clrType == typeof(double) || clrType == typeof(short) || clrType == typeof(uint) || clrType == typeof(ulong) ) && !column.IsNullable && defaultSetting == "((0))") { defaultSetting = null; } //TODO: object def = GetDefault(clrType); } catch (Exception ex) { } } if (defaultSetting != null) //TODO: non-nullable numerics will have default 0, so ((0)) can be ignored. etc. { dbContextWriter.Write($"{Environment.NewLine} .HasDefaultValueSql(\"{defaultSetting}\")"); } if (!column.IsNullable && column.ClrType == "System.String" && !column.IsPrimaryKeyMember) // reference types are always nullable (no need "?"), so must specify this. { dbContextWriter.Write($"{Environment.NewLine} .IsRequired()"); } if (column.ClrType == "System.String" && column.MaxLength != -1) { dbContextWriter.Write($"{Environment.NewLine} .HasMaxLength({column.MaxLength})"); } if (column.SqlDataType == "char" || column.SqlDataType == "nchar") { dbContextWriter.Write($"{Environment.NewLine} .IsFixedLength()"); } if (!string.IsNullOrEmpty(column.ColumnDescription)) { dbContextWriter.Write($"{Environment.NewLine} .HasComment(\"{column.ColumnDescription.Replace("\"", "\\\"")}\")"); } dbContextWriter.WriteLine($";{Environment.NewLine}"); /* * bool hasLineBreaks = false; * * if (!string.IsNullOrEmpty(c.DefaultSetting)) * { * if (!hasLineBreaks) { dbContextWriter.IncreaseIndent(); hasLineBreaks = true; } * dbContextWriter.WriteLine($"{Environment.NewLine}.HasDefaultValueSql(\"{c.DefaultSetting}\")"); * } * if (c.SqlDataType == "char" || c.SqlDataType == "nchar") * { * if (!hasLineBreaks) { dbContextWriter.IncreaseIndent(); hasLineBreaks = true; } * dbContextWriter.WriteLine($"{Environment.NewLine}.IsFixedLength()"); * } * * if (!string.IsNullOrEmpty(c.ColumnDescription)) * dbContextWriter.WriteLine($".HasComment(\"{c.ColumnDescription.Replace("\"", "\\\"")}\");"); * * if (hasLineBreaks) * dbContextWriter.DecreaseIndent(); * dbContextWriter.WriteLine(); */ } foreach (var childToParentFK in table.ForeignKeys .OrderBy(fk => fk.NavigationPropertyName) ) { var fkTable = table; var pkTable = schema.Tables.Single(t => t.TableSchema == childToParentFK.PKTableSchema && t.TableName == childToParentFK.PKTableName); var parentToChildFK = pkTable.ChildForeignKeys.Single(fk => fk.ForeignKeyConstraintName == childToParentFK.ForeignKeyConstraintName); var fkCol = fkTable.Columns.Single(c => c.ColumnName == childToParentFK.Columns.First().FKColumnName); //TODO: composite keys dbContextWriter.Write($"{Environment.NewLine}entity.HasOne(d => d.{childToParentFK.NavigationPropertyName})"); using (dbContextWriter.WithIndent()) { dbContextWriter.Write($"{Environment.NewLine}.WithMany(p => p.{parentToChildFK.NavigationPropertyName})"); dbContextWriter.Write($"{Environment.NewLine}.HasForeignKey(d => d.{GetPropertyNameForDatabaseColumn(fkTable, fkCol)})"); // NO_ACTION seems like a bug in ef dbcontext scaffold when we use -d (annotations) ? if (parentToChildFK.OnDeleteCascade == "SET_NULL" || (withAttributes && parentToChildFK.OnDeleteCascade == "NO_ACTION")) { dbContextWriter.Write($"{Environment.NewLine}.OnDelete(DeleteBehavior.ClientSetNull)"); } dbContextWriter.WriteLine($";"); } } } } } } } } #endregion // since no errors happened, let's save all files _generatorContext.SaveFiles(outputFolder: TargetFolder); Console.WriteLine("Success!"); }