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}");
                            }
                        });
                    });
                });
            });
        }
Beispiel #2
0
        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}");
                                }
                            }
                        });
                    });
                });
            });
        }
Beispiel #3
0
        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}");
                                }
                            });
                        });
                    });
                });
            });
        }
Beispiel #4
0
        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);
                            }
                        });
                    });
                });
            });
        }