protected virtual void GenerateModelInterface(ITable table, FileBuilder fileBuilder) { if (!Options.GenerateModelsInterfaces) { return; } var tableNamespace = TableNamespace(table); var tableClassName = TableClassName(table); var modelInterfaceName = ModelInterfaceName(table); var tableClassFullName = TableClassFullName(table); var tableClass = GenerationContext.FindClass(tableClassName, tableNamespace); if (!Options.OutputToSingleFile) { var filePath = $"{Options.OutputDir}{Path.DirectorySeparatorChar}{modelInterfaceName}.generated.cs"; fileBuilder.Path(filePath); } fileBuilder.Namespace(tableNamespace, true, ns => { ns.Interface(modelInterface => { // set basic info. modelInterface.Partial(true).Name(modelInterfaceName); // set properties. table.Columns.ForEach(column => { modelInterface.Property(columnProperty => { var type = DataTypeResolver.ResolveType(column); var typeName = type.GetOutputType(); bool isPropertyNullable = column.IsNullable || Options.GenerateModelPropertyAsNullable; if (type.IsValueType && isPropertyNullable) { typeName = $"{typeName}?"; } columnProperty .AccessModifier(AccessModifiers.Omit) .Name(column.Name) .Type(typeName) .Meta(column); }); }); }); }); }
private void GenerateEntity(ITable table, FileBuilder fileBuilder) { var tableNamespace = TableNamespace(table); var tableClassName = TableClassName(table); var tableInterfaceName = TableInterfaceName(table); if (!Options.OutputToSingleFile) { var filePath = $"{Options.OutputDir}{Path.DirectorySeparatorChar}{tableClassName}.generated.cs"; fileBuilder.Path(filePath); } fileBuilder.Namespace(tableNamespace, true, ns => { ns.Class(tableClass => { // set basic info. tableClass.Partial(true).Name(tableClassName); if (Options.GenerateInterfaces) { tableClass.Inherits(tableInterfaceName); } // set properties. table.Columns.ForEach(column => { tableClass.Property(columnProperty => { var type = DataTypeResolver.ResolveType(column); var typeName = type.GetOutputType(); if (type.IsValueType && column.IsNullable) { typeName = $"{typeName}?"; } columnProperty .Name(column.Name) .Type(typeName) .Meta(column); }); }); }); }); }
protected virtual void GenerateEntityInterface(ITable table, FileBuilder fileBuilder) { if (!Options.GenerateInterfaces) { return; } var tableNamespace = TableNamespace(table); var tableClassName = TableClassName(table); var tableInterfaceName = TableInterfaceName(table); if (!Options.OutputToSingleFile) { var filePath = $"{Options.OutputDir}{Path.DirectorySeparatorChar}{tableInterfaceName}.generated.cs"; fileBuilder.Path(filePath); } fileBuilder.Namespace(tableNamespace, true, ns => { ns.Interface(tableInterface => { tableInterface.Partial(true).Name(tableInterfaceName); table.Columns.ForEach(column => { tableInterface.Property(columnProperty => { var type = DataTypeResolver.ResolveType(column); var typeName = type.GetOutputType(); if (type.IsValueType && column.IsNullable) { typeName = $"{typeName}?"; } columnProperty .Name(column.Name) .AccessModifier(AccessModifiers.Omit) .Type(typeName) .Meta(column); }); }); }); }); }
protected virtual void GenerateModel(ITable table, FileBuilder fileBuilder) { if (!Options.GenerateModels) { return; } var tableNamespace = TableNamespace(table); var tableClassName = TableClassName(table); var modelClassName = ModelClassName(table); var modelInterfaceName = ModelInterfaceName(table); var tableClassFullName = TableClassFullName(table); var tableClass = GenerationContext.FindClass(tableClassName, tableNamespace); if (!Options.OutputToSingleFile) { var filePath = $"{Options.OutputDir}{Path.DirectorySeparatorChar}{modelClassName}.generated.cs"; fileBuilder.Path(filePath); } fileBuilder.Namespace(tableNamespace, true, ns => { ns.Class(modelClass => { // set basic info. modelClass.Partial(true).Name(modelClassName); if (Options.GenerateModelsInterfaces) { modelClass.Inherits(modelInterfaceName); } Options?.ModelInheritances.ForEach(mi => { modelClass.Inherits(ReplaceMetas(mi, table)); }); MethodBuilder from = null; MethodBuilder to = null; modelClass.Method(m => { m .AccessModifier(AccessModifiers.Public) .Virtual(true) .ReturnType("void") .Name("From") .Parameter(p => p.Type(tableClassFullName).Name("entity")); from = m; }); modelClass.Method(m => { m .AccessModifier(AccessModifiers.Public) .Virtual(true) .ReturnType("void") .Name("To") .Parameter(p => p.Type(tableClassFullName).Name("entity")); to = m; }); modelClass.Method(m => m .Virtual(true) .ReturnType("System.Type") .Name("GetContextType") .RawLine($"return typeof({ContextFullClassName()})") ); modelClass.Method(m => m .ReturnType("System.Type") .Name("GetEntityType") .RawLine($"return typeof({tableClassFullName})") ); // set properties. table.Columns.ForEach(column => { modelClass.Property(columnProperty => { var type = DataTypeResolver.ResolveType(column); var typeName = type.GetOutputType(); bool isPropertyNullable = column.IsNullable || Options.GenerateModelPropertyAsNullable; if (type.IsValueType && isPropertyNullable) { typeName = $"{typeName}?"; } columnProperty .Virtual(true) .Name(column.Name) .Type(typeName) .Meta(column); from.RawLine($"{column.Name} = entity.{column.Name}"); if (isPropertyNullable && !column.IsNullable) { var matchingProp = tableClass.FindByMeta <PropertyBuilder>(column); var ternary = TernaryBuilder .Create() .RawCondition(rc => rc.Condition($"{column.Name} != null")) .True(RawInlineBuilder.Create($"entity.{column.Name} = ({matchingProp.GetTypeName()}){column.Name}")) .False(RawInlineBuilder.Create($"entity.{column.Name} = default({matchingProp.GetTypeName()})")); to.RawLine($"entity.{column.Name} = {ternary.GenerateInline()}"); } else { to.RawLine($"entity.{column.Name} = {column.Name}"); } }); }); }); }); }
// TODO refactor. move to SQL SERVER EF6 /// <summary> /// //method.RawLine($"return Database.SqlQuery<{outputType}>(\"SELECT NEXT VALUE FOR [{sequence.Schema}].[{sequence.Name}];\").First()"); /// </summary> /// <param name="method"></param> /// <param name="outputType"></param> /// <param name="sequence"></param> //protected abstract void GenerateGetNextSequenceLines(MethodBuilder method, string outputType, ISequence sequence); private void GenerateEntityFluentConfiguration(ITable table, FileBuilder fileBuilder) { var tableNamespace = TableNamespace(table); var tableFluentConfigurationClassName = $"{TableClassName(table)}{Options.FluentConfigurationClassSuffix}"; var tableClassName = TableClassName(table); var tableClassFullName = TableClassFullName(table); var entityClass = GenerationContext.FindClass(tableClassName, tableNamespace); // set the path. var outputDir = Options.OutputDir; var filePath = Options.OutputToSingleFile ? $"{outputDir}\\{Options.OutputSingleFileName}" : $"{outputDir}\\{tableFluentConfigurationClassName}.generated.cs"; fileBuilder.Path(filePath); // set the namespace. fileBuilder.Namespace(tableNamespace, true, ns => { ns.Class(tableFluentConfigurationClassName, true, fluentConfigClass => { fluentConfigClass .Partial(true) .Inherits($"System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<{tableClassName}>") .Constructor(constructor => { constructor.AddComment("Table mapping & keys"); // to table mapping. constructor.RawLine(ToTableFluent(table)); // pk mapping. var pk = table.Columns.FirstOrDefault(t => t.IsPrimaryKey); var pkProp = entityClass.FindByMeta <PropertyBuilder>(pk); constructor.RawLine($"HasKey(t => t.{pkProp.GetName()})"); constructor.AddComment("Columns"); // columns mapping. table.Columns.ForEach(column => { var columnProp = entityClass.FindByMeta <PropertyBuilder>(column); var columnLine = RawLineBuilder.Create(); columnLine.Append($"Property(t => t.{columnProp.GetName()})"); columnLine.Append($".HasColumnName(\"{column.Name}\")"); if (column.IsNullable) { columnLine.Append(".IsOptional()"); } else { columnLine.Append(".IsRequired()"); } columnLine.Append($".HasColumnType(\"{column.DataType}\")"); if (column.IsPrimaryKey) { if (IsGenerateOptionIdentity(column)) { columnLine.Append(".HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)"); } else { columnLine.Append(".HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)"); } /* * // TODO make overridable class method here called IsGenerateOptionIdentity(IColumn) * if (column.IsAutoIncrement) * columnLine.Append(".HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)"); * else if (column.DataType == "uniqueidentifier" && column.DefaultValue.IndexOf("newsequentialid", StringComparison.InvariantCultureIgnoreCase) > -1) * columnLine.Append(".HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)"); * else * columnLine.Append(".HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)"); */ } if (column.CharacterMaximumLength.HasValue && column.CharacterMaximumLength != -1) { columnLine.Append($".HasMaxLength({column.CharacterMaximumLength})"); } if (DataTypeResolver.IsFixLength(column)) { columnLine.Append(".IsFixedLength()"); } if (DataTypeResolver.IsString(column) && !DataTypeResolver.IsUnicode(column)) { columnLine.Append(".IsUnicode(false)"); } if (column.NumericPrecision.HasValue && column.NumericScale.HasValue && column.NumericScale != 0) { columnLine.Append($".HasPrecision({column.NumericPrecision}, {column.NumericScale})"); } constructor.Add(columnLine); }); constructor.AddComment("Navigations"); table.ForeignKeys.ForEach(fk => { var fkProp = entityClass.FindByMeta <PropertyBuilder>(fk); var fkColumnProp = entityClass.FindByMeta <PropertyBuilder>(fk.ForeignKeyColumn); // if null meaning its being filtered. (excluded table from generation) if (fkProp != null) { var line = RawLineBuilder.Create(); var primaryNamespace = TableNamespace(fk.PrimaryKeyColumn.Table); var primaryClassName = TableClassName(fk.PrimaryKeyColumn.Table); var primaryEntity = GenerationContext.FindClass(primaryClassName, primaryNamespace); var reverseNav = primaryEntity.FindByMeta <PropertyBuilder>(fk); if (fk.ForeignKeyColumn.IsNullable) { line.Append($"HasOptional(t => t.{fkProp.GetName()})"); } else { line.Append($"HasRequired(t => t.{fkProp.GetName()})"); } if (fk.IsOneToOne()) { line.Append($".WithOptional(t => t.{reverseNav.GetName()})"); } else { line.Append($".WithMany(t => t.{reverseNav.GetName()})"); line.Append($".HasForeignKey(t => t.{fkColumnProp.GetName()})"); } constructor.Add(line); } }); constructor.AddComment("Many to Many"); table.ManyToMany().ToList().ForEach(mtm => { if (mtm.ForeignKeyColumn.PrimaryKeyOrder > 1) { return; } var manyToManyTable = mtm.ForeignKeyColumn.Table; var otherFk = mtm.ForeignKeyColumn.Table.ForeignKeys.First(t => t.ForeignKeyColumn.PrimaryKeyOrder > 1); var otherFkTable = otherFk.PrimaryKeyColumn.Table; var manyProp = entityClass.FindByMeta <PropertyBuilder>(mtm); // exclude if not being generated. if (!TablesToGenerate.Contains(otherFk.PrimaryKeyColumn.Table)) { return; } var otherNamespace = TableNamespace(otherFkTable); var otherClassName = TableClassName(otherFkTable); var otherEntity = GenerationContext.FindClass(otherClassName, otherNamespace); var otherProp = otherEntity.FindByMeta <PropertyBuilder>(otherFk); var line = RawLineBuilder.Create(); line.Append($"HasMany(t => t.{manyProp.GetName()})"); line.Append($".WithMany(t => t.{otherProp.GetName()})"); line.Append($".Map(t => t.{ToTableFluent(manyToManyTable)}"); line.Append($".MapLeftKey(\"{mtm.ForeignKeyColumn.Name}\")"); line.Append($".MapRightKey(\"{otherFk.ForeignKeyColumn.Name}\"))"); constructor.Add(line); }); }); }); }); }