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}"); } }); }); }); }); }
protected virtual void GenerateModel(ITable table) { if (!Options.GenerateModels) { return; } var tableNamespace = TableNamespace(table); var modelNamespace = ModelNamespace(table); var tableClassName = TableClassName(table); var modelClassName = ModelClassName(table); var tableClassFullName = TableClassFullName(table); var tableClass = GenerationContext.FindClass(tableClassName, tableNamespace); var fileBuilder = ResolveModelFileBuilder(table); fileBuilder.Namespace(modelNamespace, true, ns => { ns.Class(modelClass => { // set basic info. modelClass.Partial(true).Name(modelClassName); if (Options.GenerateModelsInterfaces) { var modelInterfaceFullName = ModelInterfaceFullName(table); modelClass.Inherits(modelInterfaceFullName); } Options?.ModelInheritances.ForEach(mi => { modelClass.Inherits(ReplaceMetas(mi, table)); }); MethodBuilder from = null; MethodBuilder to = null; if (Options.GenerateModelsFromTo) { 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; }); } // set properties. table.Columns.ForEach(column => { modelClass.Property(columnProperty => { var typeName = GetColumnTypeName(column, ShouldGenerateModelPropertyAsNullable(column)); // Options.GenerateModelPropertyAsNullable); columnProperty .Virtual(true) .Name(column.Name) .Type(typeName) .Meta(column); if (Options.GenerateModelsFromTo) { from.RawLine($"{column.Name} = entity.{column.Name}"); bool isPropertyNullable = IsModelPropertyNullable(column); // column.IsNullable || ShouldGenerateModelPropertyAsNullable(column);// Options.GenerateModelPropertyAsNullable; 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}"); } } }); }); }); }); }
public void InterceptTable(ITable table) { if (!(Generator is IGeneratorUsingGenerationContext) || !(Generator is IGeneratorWithMeta)) { throw new Exception("Not the kind of generator expected."); } var gen = Generator as IGeneratorUsingGenerationContext; var genMeta = Generator as IGeneratorWithMeta; var options = Generator.GetOptions(); var ctx = gen.GetGenerationContext(); // model. var modelClassName = genMeta.ModelClassName(table); var modelClassNamespace = genMeta.ModelNamespace(table); var modelFullClassName = genMeta.ModelClassFullName(table); // poco. var pocoClassName = genMeta.TableClassName(table); var pocoClassNamespace = genMeta.TableNamespace(table); var pocoFullClassName = genMeta.TableClassFullName(table); // classes var pocoClass = ctx.FindClass(pocoClassName, pocoClassNamespace); var path = $"{options.OutputDir}{Path.DirectorySeparatorChar}transformations.generated.cs"; ctx.File(path, fb => { fb.Namespace("Acme.Models", true, ns => { ns.Class($"{table.Name}ModelTransformationService", true, c => { c.Method(m => { m .AccessModifier(AccessModifiers.Public) .Virtual(true) .Name("ToModel") .ReturnType("void") .Parameter(p => p.Name("source").Type(pocoFullClassName)) .Parameter(p => p.Name("model").Type(modelFullClassName)); table.Columns.ForEach(column => { m.RawLine($"model.{column.Name} = source.{column.Name}"); }); }); c.Method(m => { m .AccessModifier(AccessModifiers.Public) .Virtual(true) .Name("FromModel") .ReturnType("void") .Parameter(p => p.Name("model").Type(modelFullClassName)) .Parameter(p => p.Name("destination").Type(pocoFullClassName)); table.Columns.ForEach(column => { bool isPropertyNullable = genMeta.IsModelPropertyNullable(column);// column.IsNullable || genMeta.ShouldGenerateModelPropertyAsNullable(column); if (isPropertyNullable && !column.IsNullable) { var matchingProp = pocoClass.FindByMeta <PropertyBuilder>(column); var ternary = TernaryBuilder .Create() .RawCondition(rc => rc.Condition($"model.{column.Name} != null")) .True(RawInlineBuilder.Create( $"destination.{column.Name} = ({matchingProp.GetTypeName()})model.{column.Name}")) .False(RawInlineBuilder.Create( $"destination.{column.Name} = default({matchingProp.GetTypeName()})")); m.RawLine($"destination.{column.Name} = {ternary.GenerateInline()}"); } else { m.RawLine($"destination.{column.Name} = model.{column.Name}"); } }); }); }); }); }); }
protected virtual void GenerateModelExtensions(ITable table) { if (!Options.GenerateModelExtensions) { return; } if (!Options.GenerateModelsInterfaces && !Options.GenerateModels) { throw new Exception("Impossible to generate model extensions because neither GenerateModels or GenerateModelsInterfaces is activated."); } // full paths to model or interface var modelFullClassName = ModelClassFullName(table); var modelInterfaceFullName = ModelInterfaceFullName(table); // poco. var pocoFullInterfaceName = TableInterfaceFullName(table); var pocoFullClassName = TableClassFullName(table); // poco type. var pocoClassName = TableClassName(table); var pocoClassNamespace = TableNamespace(table); var pocoClass = GenerationContext.FindClass(pocoClassName, pocoClassNamespace); var modelExtensionNamespaceName = ModelExtensionsNamespace(table); var modelExtensionClassName = ModelExtensionsClassName(table); var fileBuilder = ResolveModelExtensionFileBuilder(table); fileBuilder.Namespace(modelExtensionNamespaceName, true, ns => { ns.Class(c => { // set basic info. c.Partial(true).Static(true).Name(modelExtensionClassName); var finalEntityType = Options.GenerateInterfaces ? pocoFullInterfaceName : pocoFullClassName; var finalModelType = Options.GenerateModelsInterfaces ? modelInterfaceFullName : modelFullClassName; c.Method(m => { m .AccessModifier(AccessModifiers.Public) .IsStatic(true) .Name("ToModel") .ReturnType("void") .Parameter(p => p.Name("source").Type($"this {finalEntityType}")) .Parameter(p => p.Name("model").Type(finalModelType)); table.Columns.ForEach(column => { m.RawLine($"model.{column.Name} = source.{column.Name}"); }); }); c.Method(m => { m .AccessModifier(AccessModifiers.Public) .IsStatic(true) .Name("FromModel") .ReturnType("void") .Parameter(p => p.Name("model").Type($"this {finalModelType}")) .Parameter(p => p.Name("destination").Type(finalEntityType)) .Parameter(p => p.Name("ignorePrimaryKey").Type("bool").DefaultValue("true")) ; table.Columns.ForEach(column => { var rawLine = ""; bool isPropertyNullable = IsModelPropertyNullable(column); // column.IsNullable || ShouldGenerateModelPropertyAsNullable(column); if (isPropertyNullable && !column.IsNullable) { var matchingProp = pocoClass.FindByMeta <PropertyBuilder>(column); var ternary = TernaryBuilder .Create() .RawCondition(rc => rc.Condition($"model.{column.Name} != null")) .True(RawInlineBuilder.Create( $"destination.{column.Name} = ({matchingProp.GetTypeName()})model.{column.Name}")) .False(RawInlineBuilder.Create( $"destination.{column.Name} = default({matchingProp.GetTypeName()})")); rawLine = $"destination.{column.Name} = {ternary.GenerateInline()}"; } else { rawLine = $"destination.{column.Name} = model.{column.Name}"; } if (column.IsPrimaryKey) { m.Add(IfBuilder.Create().RawCondition(rc => rc.Condition($"ignorePrimaryKey != true")).Add(RawLineBuilder.Create(rawLine))); } else { m.RawLine(rawLine); } }); }); }); }); }